<commit_before>//==============================================================================
// CellML annotation view details widget
//==============================================================================

#include "cellmlannotationviewdetailswidget.h"

//==============================================================================

#include "ui_cellmlannotationviewdetailswidget.h"

//==============================================================================

#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QScrollBar>

//==============================================================================

namespace OpenCOR {
namespace CellMLAnnotationView {

//==============================================================================

CellmlAnnotationViewDetailsWidget::CellmlAnnotationViewDetailsWidget(QWidget *pParent) :
    QScrollArea(pParent),
    Core::CommonWidget(pParent),
    mGui(new Ui::CellmlAnnotationViewDetailsWidget),
    mItems(Items()),
    mFormLayout(0),
    mCmetaIdValue(0)
{
    // Set up the GUI

    mGui->setupUi(this);

    // Add a widget to our scoll area and a form layout to our scroll area's
    // widget

    mWidget = new QWidget(this);
    mFormLayout = new QFormLayout(this);

    mWidget->setLayout(mFormLayout);

    setWidget(mWidget);
}

//==============================================================================

CellmlAnnotationViewDetailsWidget::~CellmlAnnotationViewDetailsWidget()
{
    // Delete the GUI

    delete mGui;
}

//==============================================================================

void CellmlAnnotationViewDetailsWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // Update the GUI (since some labels get reinitialised as a result of the
    // retranslation)

    updateGui(mItems);
}

//==============================================================================

CellmlAnnotationViewDetailsWidget::Item CellmlAnnotationViewDetailsWidget::item(const Type &pType,
                                                                                CellMLSupport::CellmlFileElement *pElement,
                                                                                const QString &pName)
{
    // Return a formatted Item 'object'

    Item res;

    res.type    = pType;
    res.element = pElement;
    res.name    = pName;

    return res;
}

//==============================================================================

void CellmlAnnotationViewDetailsWidget::updateGui(const Items &pItems)
{
    // Hide ourselves (since we may potentially update ourselves quite a bit and
    // we want to avoid any flickering)
    // Note #1: one would normally use setUpdatesEnabled(), but it still results
    //          in bad flickering on Mac OS X, so...
    // Note #2: it's surprising that setVisible() doesn't cause any flickering
    //          on any of the platforms we are targetting, but let's not
    //          complain...

    setVisible(false);

    // Keep track of the items

    mItems = pItems;

    // Remove everything from our form layout

    for (int i = 0, iMax = mFormLayout->count(); i < iMax; ++i) {
        QLayoutItem *item = mFormLayout->takeAt(0);

        delete item->widget();
        delete item;
    }

    mCmetaIdValue = 0;

    // Go through the different items which properties we want to add to the GUI

    for (int i = 0, iLast = pItems.count()-1; i <= iLast; ++i) {
        Item item = pItems.at(i);

        Q_ASSERT(   (((item.type == Empty) || (item.type == Metadata)) && !item.element)
                 || ((item.type != Empty) && (item.type != Metadata) && item.element));

        // Determine which widget should be shown/hidden

        bool showCmetaId = (item.type != Metadata) && (item.type != Empty);
        bool showName = false;
        bool showXlinkHref = false;
        bool showUnitReference = false;
        bool showComponentReference = false;
        bool showUnit = false;
        bool showInitialValue = false;
        bool showPublicInterface = false;
        bool showPrivateInterface = false;
        bool showRelationship = false;
        bool showRelationshipNamespace = false;
        bool showComponent = false;
        bool showFirstComponent = false;
        bool showSecondComponent = false;
        bool showFirstVariable = false;
        bool showSecondVariable = false;

        switch (item.type) {
        case Model:
        case Unit:
        case UnitElement:
        case Component:
        case Group:
        case Connection:
            showName = true;

            break;
        case Import:
            showXlinkHref = true;

            break;
        case ImportUnit:
            showName = true;
            showUnitReference = true;

            break;
        case ImportComponent:
            showName = true;
            showComponentReference = true;

            break;
        case Variable:
            showName = true;
            showUnit = true;
            showInitialValue = true;
            showPublicInterface = true;
            showPrivateInterface = true;

            break;
        case RelationshipReference:
            showRelationship = true;
            showRelationshipNamespace = true;

            break;
        case ComponentReference:
            showComponent = true;

            break;
        case ComponentMapping:
            showFirstComponent = true;
            showSecondComponent = true;

            break;
        case VariableMapping:
            showFirstVariable = true;
            showSecondVariable = true;

            break;
        case Metadata:
            break;
        default:
            // Empty, so...

            ;
        };

        // Add whatever we need
        // Note: as long as all of the widgets' parent is our scroll area's
        //       widget, then they will get automatically deleted, so no need to
        //       delete them in ~CellmlAnnotationViewDetailsWidget()...

        // Add a bold centered label as a header to let the user know what type
        // of item we are talking about

        QLabel *header = new QLabel(typeAsString(item.type), mWidget);

        QFont headerFont = header->font();

        headerFont.setBold(true);

        header->setAlignment(Qt::AlignCenter);
        header->setFont(headerFont);

        mFormLayout->addRow(header);

        // Show the item's properties

        if (showCmetaId) {
            // We only want to allow the editing of the very first item

            QString cmetaId = item.element->cmetaId();

            if (i == iLast) {
                // This is our 'main' current item, so we want to allow the user
                // to edit its cmeta:id

                mCmetaIdValue = new QLineEdit(cmetaId, mWidget);

                mFormLayout->addRow(new QLabel(tr("cmeta:id:"), mWidget),
                                    mCmetaIdValue);
            } else {
                // Not our 'main' current item, so just display its cmeta:id

                addRowToFormLayout(tr("cmeta:id:"),
                                   cmetaId.isEmpty()?"/":cmetaId);
            }
        }

        if (showName) {
            // Retrieve the name of the CellML element
            // Note: in the case of a group or a connection, there won't be a
            //       name, so we use the item's name, hoping one was provided...

            QString name = ((item.type == Group) || (item.type == Connection))?
                               item.name.isEmpty()?"/":item.name:
                               static_cast<CellMLSupport::CellmlFileNamedElement *>(item.element)->name();

            addRowToFormLayout(tr("Name:"), name);
        }

        if (showXlinkHref)
            addRowToFormLayout(tr("xlink:href:"),
                               static_cast<CellMLSupport::CellmlFileImport *>(item.element)->xlinkHref());

        if (showUnitReference)
            addRowToFormLayout(tr("Unit reference:"),
                               static_cast<CellMLSupport::CellmlFileImportUnit *>(item.element)->unitReference());

        if (showComponentReference)
            addRowToFormLayout(tr("Component reference:"),
                               static_cast<CellMLSupport::CellmlFileImportComponent *>(item.element)->componentReference());

        if (showUnit)
            addRowToFormLayout(tr("Unit:"),
                               static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->unit());

        if (showInitialValue) {
            QString initialValue = static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->initialValue();

            addRowToFormLayout(tr("Initial value:"),
                               initialValue.isEmpty()?"/":initialValue);
        }

        if (showPublicInterface)
            addRowToFormLayout(tr("Public interface:"),
                               static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->publicInterfaceAsString());

        if (showPrivateInterface)
            addRowToFormLayout(tr("Private interface:"),
                               static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->privateInterfaceAsString());

        if (showRelationship)
            addRowToFormLayout(tr("Relationship:"),
                               static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationship());

        if (showRelationshipNamespace) {
            QString relationshipNamespace = static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationshipNamespace();

            addRowToFormLayout(tr("Relationship namespace:"),
                               relationshipNamespace.isEmpty()?"/":relationshipNamespace);
        }

        if (showComponent)
            addRowToFormLayout(tr("Component:"),
                               static_cast<CellMLSupport::CellmlFileComponentReference *>(item.element)->component());

        if (showFirstComponent)
            addRowToFormLayout(tr("First component:"),
                               static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->firstComponent());

        if (showSecondComponent)
            addRowToFormLayout(tr("Second component:"),
                               static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->secondComponent());

        if (showFirstVariable)
            addRowToFormLayout(tr("First variable:"),
                               static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->firstVariable());

        if (showSecondVariable)
            addRowToFormLayout(tr("Second variable:"),
                               static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->secondVariable());
    }

    // Re-show ourselves

    setVisible(true);

    // Scroll to the bottom of ourselves, just in case things don't fit within
    // the viewport
    // Note: for this, we need to be up-to-date, hence we make a call to
    //       qApp->processEvents() and this can only be done when we are once
    //       again visible...

    qApp->processEvents();

    verticalScrollBar()->setValue(verticalScrollBar()->maximum());

    // Give the focus to the cmeta:id value field
    // Note: indeed, to have the cmeta:id value field as a focus proxy widget
    //       for CellmlAnnotationViewWidget isn't good enough to have it get the
    //       focus after selecting a 'new' CellML element in
    //       CellmlAnnotationViewWidget (while it's when we switch from one
    //       CellML file to another), so...

    mCmetaIdValue->setFocus();
}

//==============================================================================

void CellmlAnnotationViewDetailsWidget::addRowToFormLayout(const QString &pLabel,
                                                           const QString &pValue)
{
    // Add a row to our form layout

    mFormLayout->addRow(new QLabel(pLabel, mWidget),
                        new QLabel(pValue, mWidget));
}

//==============================================================================

QString CellmlAnnotationViewDetailsWidget::typeAsString(const Type &pType) const
{
    switch (pType) {
    case Model:
        return tr("Model");
    case Import:
        return tr("Import");
    case ImportUnit:
        return tr("Imported unit");
    case ImportComponent:
        return tr("Imported component");
    case Unit:
        return tr("Unit");
    case UnitElement:
        return tr("Unit element");
    case Component:
        return tr("Component");
    case Variable:
        return tr("Variable");
    case Group:
        return tr("Group");
    case RelationshipReference:
        return tr("Relationshop reference");
    case ComponentReference:
        return tr("Component reference");
    case Connection:
        return tr("Connection");
    case ComponentMapping:
        return tr("Component mapping");
    case VariableMapping:
        return tr("Variable mapping");
    case Metadata:
        return tr("Metadata");
    default:
        // Empty

        return QString();
    }
}

//==============================================================================

QWidget * CellmlAnnotationViewDetailsWidget::focusProxyWidget()
{
    // If anything, we want our cmeta:id value widget to be a focus proxy widget

    return mCmetaIdValue;
}

//==============================================================================

}   // namespace CellMLAnnotationView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some work on the CellML Annotation view for a CellML file (#78).<commit_after>//==============================================================================
// CellML annotation view details widget
//==============================================================================

#include "cellmlannotationviewdetailswidget.h"

//==============================================================================

#include "ui_cellmlannotationviewdetailswidget.h"

//==============================================================================

#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QScrollBar>

//==============================================================================

namespace OpenCOR {
namespace CellMLAnnotationView {

//==============================================================================

CellmlAnnotationViewDetailsWidget::CellmlAnnotationViewDetailsWidget(QWidget *pParent) :
    QScrollArea(pParent),
    Core::CommonWidget(pParent),
    mGui(new Ui::CellmlAnnotationViewDetailsWidget),
    mItems(Items()),
    mFormLayout(0),
    mCmetaIdValue(0)
{
    // Set up the GUI

    mGui->setupUi(this);

    // Add a widget to our scoll area and a form layout to our scroll area's
    // widget

    mWidget = new QWidget(this);
    mFormLayout = new QFormLayout(this);

    mWidget->setLayout(mFormLayout);

    setWidget(mWidget);
}

//==============================================================================

CellmlAnnotationViewDetailsWidget::~CellmlAnnotationViewDetailsWidget()
{
    // Delete the GUI

    delete mGui;
}

//==============================================================================

void CellmlAnnotationViewDetailsWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // Update the GUI (since some labels get reinitialised as a result of the
    // retranslation)

    updateGui(mItems);
}

//==============================================================================

CellmlAnnotationViewDetailsWidget::Item CellmlAnnotationViewDetailsWidget::item(const Type &pType,
                                                                                CellMLSupport::CellmlFileElement *pElement,
                                                                                const QString &pName)
{
    // Return a formatted Item 'object'

    Item res;

    res.type    = pType;
    res.element = pElement;
    res.name    = pName;

    return res;
}

//==============================================================================

void CellmlAnnotationViewDetailsWidget::updateGui(const Items &pItems)
{
    // Hide ourselves (since we may potentially update ourselves quite a bit and
    // we want to avoid any flickering)
    // Note #1: one would normally use setUpdatesEnabled(), but it still results
    //          in bad flickering on Mac OS X, so...
    // Note #2: it's surprising that setVisible() doesn't cause any flickering
    //          on any of the platforms we are targetting, but let's not
    //          complain...

    setVisible(false);

    // Keep track of the items

    mItems = pItems;

    // Remove everything from our form layout

    for (int i = 0, iMax = mFormLayout->count(); i < iMax; ++i) {
        QLayoutItem *item = mFormLayout->takeAt(0);

        delete item->widget();
        delete item;
    }

    mCmetaIdValue = 0;

    // Go through the different items which properties we want to add to the GUI

    for (int i = 0, iLast = pItems.count()-1; i <= iLast; ++i) {
        Item item = pItems.at(i);

        Q_ASSERT(   (((item.type == Empty) || (item.type == Metadata)) && !item.element)
                 || ((item.type != Empty) && (item.type != Metadata) && item.element));

        // Determine which widget should be shown/hidden

        bool showCmetaId = (item.type != Metadata) && (item.type != Empty);
        bool showName = false;
        bool showXlinkHref = false;
        bool showUnitReference = false;
        bool showComponentReference = false;
        bool showUnit = false;
        bool showInitialValue = false;
        bool showPublicInterface = false;
        bool showPrivateInterface = false;
        bool showRelationship = false;
        bool showRelationshipNamespace = false;
        bool showComponent = false;
        bool showFirstComponent = false;
        bool showSecondComponent = false;
        bool showFirstVariable = false;
        bool showSecondVariable = false;

        switch (item.type) {
        case Model:
        case Unit:
        case UnitElement:
        case Component:
        case Group:
        case Connection:
            showName = true;

            break;
        case Import:
            showXlinkHref = true;

            break;
        case ImportUnit:
            showName = true;
            showUnitReference = true;

            break;
        case ImportComponent:
            showName = true;
            showComponentReference = true;

            break;
        case Variable:
            showName = true;
            showUnit = true;
            showInitialValue = true;
            showPublicInterface = true;
            showPrivateInterface = true;

            break;
        case RelationshipReference:
            showRelationship = true;
            showRelationshipNamespace = true;

            break;
        case ComponentReference:
            showComponent = true;

            break;
        case ComponentMapping:
            showFirstComponent = true;
            showSecondComponent = true;

            break;
        case VariableMapping:
            showFirstVariable = true;
            showSecondVariable = true;

            break;
        case Metadata:
            break;
        default:
            // Empty, so...

            ;
        };

        // Add whatever we need
        // Note: as long as all of the widgets' parent is our scroll area's
        //       widget, then they will get automatically deleted, so no need to
        //       delete them in ~CellmlAnnotationViewDetailsWidget()...

        // Add a bold centered label as a header to let the user know what type
        // of item we are talking about

        QLabel *header = new QLabel(typeAsString(item.type), mWidget);

        QFont headerFont = header->font();

        headerFont.setBold(true);

        header->setAlignment(Qt::AlignCenter);
        header->setFont(headerFont);

        mFormLayout->addRow(header);

        // Show the item's properties

        if (showCmetaId) {
            // We only want to allow the editing of the very first item

            QString cmetaId = item.element->cmetaId();

            if (i == iLast) {
                // This is our 'main' current item, so we want to allow the user
                // to edit its cmeta:id

                mCmetaIdValue = new QLineEdit(cmetaId, mWidget);

                mFormLayout->addRow(new QLabel(tr("cmeta:id:"), mWidget),
                                    mCmetaIdValue);
            } else {
                // Not our 'main' current item, so just display its cmeta:id

                addRowToFormLayout(tr("cmeta:id:"),
                                   cmetaId.isEmpty()?"/":cmetaId);
            }
        }

        if (showName) {
            // Retrieve the name of the CellML element
            // Note: in the case of a group or a connection, there won't be a
            //       name, so we use the item's name, hoping one was provided...

            QString name = ((item.type == Group) || (item.type == Connection))?
                               item.name.isEmpty()?"/":item.name:
                               static_cast<CellMLSupport::CellmlFileNamedElement *>(item.element)->name();

            addRowToFormLayout(tr("Name:"), name);
        }

        if (showXlinkHref)
            addRowToFormLayout(tr("xlink:href:"),
                               static_cast<CellMLSupport::CellmlFileImport *>(item.element)->xlinkHref());

        if (showUnitReference)
            addRowToFormLayout(tr("Unit reference:"),
                               static_cast<CellMLSupport::CellmlFileImportUnit *>(item.element)->unitReference());

        if (showComponentReference)
            addRowToFormLayout(tr("Component reference:"),
                               static_cast<CellMLSupport::CellmlFileImportComponent *>(item.element)->componentReference());

        if (showUnit)
            addRowToFormLayout(tr("Unit:"),
                               static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->unit());

        if (showInitialValue) {
            QString initialValue = static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->initialValue();

            addRowToFormLayout(tr("Initial value:"),
                               initialValue.isEmpty()?"/":initialValue);
        }

        if (showPublicInterface)
            addRowToFormLayout(tr("Public interface:"),
                               static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->publicInterfaceAsString());

        if (showPrivateInterface)
            addRowToFormLayout(tr("Private interface:"),
                               static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->privateInterfaceAsString());

        if (showRelationship)
            addRowToFormLayout(tr("Relationship:"),
                               static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationship());

        if (showRelationshipNamespace) {
            QString relationshipNamespace = static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationshipNamespace();

            addRowToFormLayout(tr("Relationship namespace:"),
                               relationshipNamespace.isEmpty()?"/":relationshipNamespace);
        }

        if (showComponent)
            addRowToFormLayout(tr("Component:"),
                               static_cast<CellMLSupport::CellmlFileComponentReference *>(item.element)->component());

        if (showFirstComponent)
            addRowToFormLayout(tr("First component:"),
                               static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->firstComponent());

        if (showSecondComponent)
            addRowToFormLayout(tr("Second component:"),
                               static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->secondComponent());

        if (showFirstVariable)
            addRowToFormLayout(tr("First variable:"),
                               static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->firstVariable());

        if (showSecondVariable)
            addRowToFormLayout(tr("Second variable:"),
                               static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->secondVariable());
    }

    // Re-show ourselves

    setVisible(true);

    // Scroll to the bottom of ourselves, just in case things don't fit within
    // the viewport
    // Note: for this, we need to be up-to-date, hence we make a call to
    //       qApp->processEvents() and this can only be done when we are once
    //       again visible...

    qApp->processEvents();

    verticalScrollBar()->setValue(verticalScrollBar()->maximum());

    // Give the focus to the cmeta:id value field
    // Note: indeed, to have the cmeta:id value field as a focus proxy widget
    //       for CellmlAnnotationViewWidget isn't good enough to have it get the
    //       focus after selecting a 'new' CellML element in
    //       CellmlAnnotationViewWidget (while it's when we switch from one
    //       CellML file to another), so...

    if (mCmetaIdValue)
        mCmetaIdValue->setFocus();
}

//==============================================================================

void CellmlAnnotationViewDetailsWidget::addRowToFormLayout(const QString &pLabel,
                                                           const QString &pValue)
{
    // Add a row to our form layout

    mFormLayout->addRow(new QLabel(pLabel, mWidget),
                        new QLabel(pValue, mWidget));
}

//==============================================================================

QString CellmlAnnotationViewDetailsWidget::typeAsString(const Type &pType) const
{
    switch (pType) {
    case Model:
        return tr("Model");
    case Import:
        return tr("Import");
    case ImportUnit:
        return tr("Imported unit");
    case ImportComponent:
        return tr("Imported component");
    case Unit:
        return tr("Unit");
    case UnitElement:
        return tr("Unit element");
    case Component:
        return tr("Component");
    case Variable:
        return tr("Variable");
    case Group:
        return tr("Group");
    case RelationshipReference:
        return tr("Relationshop reference");
    case ComponentReference:
        return tr("Component reference");
    case Connection:
        return tr("Connection");
    case ComponentMapping:
        return tr("Component mapping");
    case VariableMapping:
        return tr("Variable mapping");
    case Metadata:
        return tr("Metadata");
    default:
        // Empty

        return QString();
    }
}

//==============================================================================

QWidget * CellmlAnnotationViewDetailsWidget::focusProxyWidget()
{
    // If anything, we want our cmeta:id value widget to be a focus proxy widget

    return mCmetaIdValue;
}

//==============================================================================

}   // namespace CellMLAnnotationView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>#include "xcompositeeglintegration.h"

#include "waylandobject.h"
#include "wayland_wrapper/wlcompositor.h"
#include "wayland-xcomposite-server-protocol.h"

#include <QtGui/QPlatformNativeInterface>
#include <QtGui/QPlatformGLContext>
#include <private/qapplication_p.h>

#include "xcompositebuffer.h"
#include "xcompositehandler.h"
#include <X11/extensions/Xcomposite.h>

#include <QtCore/QDebug>

QVector<EGLint> eglbuildSpec()
{
    QVector<EGLint> spec;

    spec.append(EGL_SURFACE_TYPE); spec.append(EGL_PIXMAP_BIT);
    spec.append(EGL_RENDERABLE_TYPE); spec.append(EGL_OPENGL_ES2_BIT);
    spec.append(EGL_BIND_TO_TEXTURE_RGB); spec.append(EGL_TRUE);
    spec.append(EGL_NONE);
    return spec;
}

struct wl_xcomposite_interface XCompositeHandler::xcomposite_interface = {
    XCompositeHandler::create_buffer
};

GraphicsHardwareIntegration *GraphicsHardwareIntegration::createGraphicsHardwareIntegration(WaylandCompositor *compositor)
{
    return new XCompositeEglIntegration(compositor);
}

XCompositeEglIntegration::XCompositeEglIntegration(WaylandCompositor *compositor)
    : GraphicsHardwareIntegration(compositor)
    , mDisplay(0)
{
    QPlatformNativeInterface *nativeInterface = QApplicationPrivate::platformIntegration()->nativeInterface();
    if (nativeInterface) {
        mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWidget("Display",m_compositor->topLevelWidget()));
        if (!mDisplay)
            qFatal("could not retireve Display from platform integration");
        mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWidget("EGLDisplay",m_compositor->topLevelWidget()));
        if (!mEglDisplay)
            qFatal("could not retrieve EGLDisplay from plaform integration");
    } else {
        qFatal("Platform integration doesn't have native interface");
    }
    mScreen = XDefaultScreen(mDisplay);
}

void XCompositeEglIntegration::initializeHardware(Wayland::Display *waylandDisplay)
{
    XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->topLevelWidget());
    waylandDisplay->addGlobalObject(handler->base(), &wl_xcomposite_interface, &XCompositeHandler::xcomposite_interface,XCompositeHandler::send_root_information);

    QPlatformGLContext *glContext = m_compositor->topLevelWidget()->platformWindow()->glContext();

}

GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer)
{
    XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
    Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());

    QVector<EGLint> eglConfigSpec = eglbuildSpec();

    EGLint matching = 0;
    EGLConfig config;
    bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching);
    if (!matched || !matching) {
        qWarning("Could not retrieve a suitable EGL config");
        return 0;
    }

    QVector<EGLint> attribList;

    attribList.append(EGL_TEXTURE_FORMAT);
    attribList.append(EGL_TEXTURE_RGB);
    attribList.append(EGL_TEXTURE_TARGET);
    attribList.append(EGL_TEXTURE_2D);
    attribList.append(EGL_NONE);

    EGLSurface surface = eglCreatePixmapSurface(mEglDisplay,config,pixmap,attribList.constData());
    if (surface == EGL_NO_SURFACE) {
        qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window();
    }

    compositorBuffer->setInvertedY(false);

    GLuint textureId;
    glGenTextures(1,&textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);

    if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) {
        qDebug() << "Failed to bind";
    }

    //    eglDestroySurface(mEglDisplay,surface);

    return textureId;
}

bool XCompositeEglIntegration::isYInverted(wl_buffer *buffer) const
{
    XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
    return compositorBuffer->isYInverted();
}
<commit_msg>Handle surfaces with alpha channel in xcomposite_egl<commit_after>#include "xcompositeeglintegration.h"

#include "waylandobject.h"
#include "wayland_wrapper/wlcompositor.h"
#include "wayland-xcomposite-server-protocol.h"

#include <QtGui/QPlatformNativeInterface>
#include <QtGui/QPlatformGLContext>
#include <private/qapplication_p.h>

#include "xcompositebuffer.h"
#include "xcompositehandler.h"
#include <X11/extensions/Xcomposite.h>

#include <QtCore/QDebug>

QVector<EGLint> eglbuildSpec()
{
    QVector<EGLint> spec;

    spec.append(EGL_SURFACE_TYPE); spec.append(EGL_PIXMAP_BIT);
    spec.append(EGL_RENDERABLE_TYPE); spec.append(EGL_OPENGL_ES2_BIT);
    spec.append(EGL_BIND_TO_TEXTURE_RGBA); spec.append(EGL_TRUE);
    spec.append(EGL_ALPHA_SIZE); spec.append(8);
    spec.append(EGL_NONE);
    return spec;
}

struct wl_xcomposite_interface XCompositeHandler::xcomposite_interface = {
    XCompositeHandler::create_buffer
};

GraphicsHardwareIntegration *GraphicsHardwareIntegration::createGraphicsHardwareIntegration(WaylandCompositor *compositor)
{
    return new XCompositeEglIntegration(compositor);
}

XCompositeEglIntegration::XCompositeEglIntegration(WaylandCompositor *compositor)
    : GraphicsHardwareIntegration(compositor)
    , mDisplay(0)
{
    QPlatformNativeInterface *nativeInterface = QApplicationPrivate::platformIntegration()->nativeInterface();
    if (nativeInterface) {
        mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWidget("Display",m_compositor->topLevelWidget()));
        if (!mDisplay)
            qFatal("could not retireve Display from platform integration");
        mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForWidget("EGLDisplay",m_compositor->topLevelWidget()));
        if (!mEglDisplay)
            qFatal("could not retrieve EGLDisplay from plaform integration");
    } else {
        qFatal("Platform integration doesn't have native interface");
    }
    mScreen = XDefaultScreen(mDisplay);
}

void XCompositeEglIntegration::initializeHardware(Wayland::Display *waylandDisplay)
{
    XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->topLevelWidget());
    waylandDisplay->addGlobalObject(handler->base(), &wl_xcomposite_interface, &XCompositeHandler::xcomposite_interface,XCompositeHandler::send_root_information);

    QPlatformGLContext *glContext = m_compositor->topLevelWidget()->platformWindow()->glContext();

}

GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer)
{
    XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
    Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());

    QVector<EGLint> eglConfigSpec = eglbuildSpec();

    EGLint matching = 0;
    EGLConfig config;
    bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching);
    if (!matched || !matching) {
        qWarning("Could not retrieve a suitable EGL config");
        return 0;
    }

    QVector<EGLint> attribList;

    attribList.append(EGL_TEXTURE_FORMAT);
    attribList.append(EGL_TEXTURE_RGBA);
    attribList.append(EGL_TEXTURE_TARGET);
    attribList.append(EGL_TEXTURE_2D);
    attribList.append(EGL_NONE);

    EGLSurface surface = eglCreatePixmapSurface(mEglDisplay,config,pixmap,attribList.constData());
    if (surface == EGL_NO_SURFACE) {
        qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window();
    }

    compositorBuffer->setInvertedY(false);

    GLuint textureId;
    glGenTextures(1,&textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);

    if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) {
        qDebug() << "Failed to bind";
    }

    //    eglDestroySurface(mEglDisplay,surface);

    return textureId;
}

bool XCompositeEglIntegration::isYInverted(wl_buffer *buffer) const
{
    XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
    return compositorBuffer->isYInverted();
}
<|endoftext|>


<commit_before>#ifdef HAVE_CMAKE_CONFIG
#include "cmake_config.h"
#elif defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#define HAVE_DUNE_DETAILED_DISCRETIZATIONS 1

#include <iostream>
#include <sstream>
#include <vector>

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/static_assert.hh>
#include <dune/common/timer.hh>
#include <dune/common/dynvector.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/discretefunction/projection/dirichlet.hh>

#include <dune/detailed/discretizations/space/continuouslagrange/fem.hh>
#include <dune/detailed/discretizations/la/containerfactory/eigen.hh>
#include <dune/detailed/discretizations/evaluation/elliptic.hh>
#include <dune/detailed/discretizations/evaluation/product.hh>
#include <dune/detailed/discretizations/localoperator/codim0.hh>
#include <dune/detailed/discretizations/localfunctional/codim0.hh>
#include <dune/detailed/discretizations/assembler/local/codim0.hh>
#include <dune/detailed/discretizations/space/constraints.hh>
#include <dune/detailed/discretizations/assembler/system.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>

const std::string id = "elliptic.continuousgalerkin";

#ifndef POLORDER
const int polOrder = 1;
#else
const int polOrder = POLORDER;
#endif
dune_static_assert((polOrder > 0), "ERROR: polOrder hast to be positive!");

using namespace Dune::Detailed::Discretizations;

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(const std::string& filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "grid = "
         << "gridprovider.cube" << std::endl;
    file << "boundaryinfo = "
         << "boundaryinfo.alldirichlet" << std::endl;
    file << "[gridprovider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = [12; 12; 12]" << std::endl;
    file << "[boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 2; 3]" << std::endl;
    file << "neumann = [4]" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.1*x[0]; 0.0; 0.0]" << std::endl;
    file << "[neumann]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "type = bicgstab.ilut" << std::endl;
    file << "maxIter = 5000" << std::endl;
    file << "precision = 1e-12" << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::Fem::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".description";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree description(argc, argv, paramFilename);
    description.assertSub(id);

    // logger
    Dune::Stuff::Common::Logger().create(Dune::Stuff::Common::LOG_INFO | Dune::Stuff::Common::LOG_CONSOLE);
    Dune::Stuff::Common::LogStream& info = Dune::Stuff::Common::Logger().info();

    // timer
    Dune::Timer timer;

    info << "setting up grid:" << std::endl;
    typedef Dune::Stuff::GridProviderInterface<> GridProviderType;
    const GridProviderType* gridProvider =
        Dune::Stuff::GridProviders<>::create(description.get(id + ".grid", "gridprovider.cube"), description);
    typedef GridProviderType::GridType GridType;
    const std::shared_ptr<const GridType> grid = gridProvider->grid();
    typedef Dune::grid::Part::Leaf::Const<GridType> GridPartType;
    typedef typename GridPartType::GridViewType GridViewType;
    const GridPartType gridPart(*grid);
    typedef typename Dune::Stuff::GridboundaryInterface<typename GridPartType::GridViewType> BoundaryInfoType;
    const std::shared_ptr<const BoundaryInfoType> boundaryInfo(
        Dune::Stuff::Gridboundaries<typename GridPartType::GridViewType>::create(
            description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"), description));
    info << "  took " << timer.elapsed() << " sec, has " << grid->size(0) << " entities" << std::endl;
    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"),
                            description,
                            description.get(id + ".filename", id) + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    const unsigned int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const unsigned int DUNE_UNUSED(dimRange) = 1;
    typedef typename GridType::ctype DomainFieldType;
    typedef double RangeFieldType;

    typedef Dune::Stuff::FunctionExpression<DomainFieldType, dimDomain, RangeFieldType, dimRange>
        ExpressionFunctionType;
    const std::shared_ptr<const ExpressionFunctionType> diffusion(
        ExpressionFunctionType::create(description.sub("diffusion")));
    const std::shared_ptr<const ExpressionFunctionType> force(ExpressionFunctionType::create(description.sub("force")));
    const std::shared_ptr<const ExpressionFunctionType> dirichlet(
        ExpressionFunctionType::create(description.sub("dirichlet")));
    const std::shared_ptr<const ExpressionFunctionType> neumann(
        ExpressionFunctionType::create(description.sub("neumann")));

    // info << "initializing discrete function spaces... " << std::flush;
    // timer.reset();
    typedef ContinuousLagrangeSpace::FemWrapper<GridPartType, polOrder, RangeFieldType, dimRange> SpaceType;
    const SpaceType space(gridPart);

    // left hand side
    // * elliptic diffusion operator
    typedef LocalOperator::Codim0Integral<Evaluation::Elliptic, ExpressionFunctionType> EllipticOperatorType;
    const EllipticOperatorType diffusionOperator(*diffusion);
    // * right hand side
    //   * L2 force functional
    typedef LocalFunctional::Codim0Integral<Evaluation::Product, ExpressionFunctionType> L2FunctionalType;
    const L2FunctionalType forceFunctional(*force);
    //   * L2 neumann functional
    const L2FunctionalType neumannFunctional(*neumann);

    info << "initializing matrix (of size " << space.mapper().size() << "x" << space.mapper().size()
         << ") and vectors... " << std::flush;
    // timer.reset();
    typedef ContainerFactoryEigen<RangeFieldType> ContainerFactory;
    typedef ContainerFactory::RowMajorSparseMatrixType MatrixType;
    typedef ContainerFactory::DenseVectorType VectorType;
    std::shared_ptr<MatrixType> systemMatrix(ContainerFactory::createRowMajorSparseMatrix(space, space));
    std::shared_ptr<VectorType> forceVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> dirichletVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> neumannVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> rhsVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> solutionVector(ContainerFactory::createDenseVector(space));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "assembing system... " << std::flush;
    timer.reset();
    // * dirichlet boundary values
    typedef DiscreteFunctionDefault<SpaceType, VectorType> DiscreteFunctionType;
    DiscreteFunctionType dirichletProjection(space, dirichletVector, "dirichlet");
    Dune::Stuff::DiscreteFunction::project(*boundaryInfo, *dirichlet, dirichletProjection);

    // * local matrix assembler
    typedef LocalAssembler::Codim0Matrix<EllipticOperatorType> LocalEllipticOperatorMatrixAssemblerType;
    const LocalEllipticOperatorMatrixAssemblerType diffusionMatrixAssembler(diffusionOperator);
    // * local vector assemblers
    typedef LocalAssembler::Codim0Vector<L2FunctionalType> LocalL2FunctionalVectorAssemblerType;
    //   * force vector
    const LocalL2FunctionalVectorAssemblerType forceVectorAssembler(forceFunctional);
    //   * neumann vector
    const LocalL2FunctionalVectorAssemblerType neumannVectorAssembler(neumannFunctional);
    // * system assembler
    typedef SystemAssembler<SpaceType, SpaceType> SystemAssemblerType;
    SystemAssemblerType systemAssembler(space);
    systemAssembler.addLocalMatrixAssembler(diffusionMatrixAssembler, *systemMatrix);
    systemAssembler.addLocalVectorAssembler(forceVectorAssembler, *forceVector);
    systemAssembler.addLocalVectorAssembler(neumannVectorAssembler, *neumannVector);
    systemAssembler.assemble();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "applying constraints... " << std::flush;
    timer.reset();
    Constraints::Dirichlet<GridViewType, RangeFieldType> dirichletConstraints(
        *boundaryInfo, space.mapper().maxNumDofs(), space.mapper().maxNumDofs());
    rhsVector->backend() =
        forceVector->backend() + neumannVector->backend() - systemMatrix->backend() * dirichletVector->backend();
    systemAssembler.applyConstraints(dirichletConstraints, *systemMatrix, *rhsVector);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "solving linear system (of size " << systemMatrix->rows() << "x" << systemMatrix->cols() << ")"
         << std::endl;
    const std::string solverType     = description.get("solver.type", "bicgstab");
    const unsigned int solverMaxIter = description.get("solver.maxIter", 5000);
    const double solverPrecision     = description.get("solver.precision", 1e-12);
    info << "  using '" << solverType << "'... " << std::flush;
    timer.reset();
    typedef typename Dune::Stuff::LA::Solver::Interface<MatrixType, VectorType> SolverType;
    std::shared_ptr<SolverType> solver(Dune::Stuff::LA::Solver::create<MatrixType, VectorType>(solverType));
    const unsigned int failure =
        solver->apply(*systemMatrix, *rhsVector, *solutionVector, solverMaxIter, solverPrecision);
    if (failure)
      DUNE_THROW(Dune::MathError, "\nERROR: linear solver '" << solverType << "' reported a problem!");
    if (solutionVector->size() != space.mapper().size())
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' produced a solution of wrong size (is "
                                            << solutionVector->size()
                                            << ", should be "
                                            << space.mapper().size()
                                            << ")!");
    solutionVector->backend() += dirichletVector->backend();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    const std::string solutionFilename = description.get(id + ".filename", id) + ".solution";
    const std::string solutionName     = id + ".solution";
    info << "writing solution to '" << solutionFilename;
    if (dimDomain == 1)
      info << ".vtp";
    else
      info << ".vtu";
    info << "'... " << std::flush;
    timer.reset();
    typedef DiscreteFunctionDefaultConst<SpaceType, VectorType> ConstDiscreteFunctionType;
    const std::shared_ptr<const ConstDiscreteFunctionType> solution(
        new ConstDiscreteFunctionType(space, solutionVector, solutionName));
    typedef Dune::VTKWriter<GridViewType> VTKWriterType;
    VTKWriterType vtkWriter(gridPart.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<commit_msg>[examples.elliptic.continuousgalerkin] update<commit_after>#ifdef HAVE_CMAKE_CONFIG
#include "cmake_config.h"
#elif defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#define HAVE_DUNE_DETAILED_DISCRETIZATIONS 1

#include <iostream>
#include <sstream>
#include <vector>

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/static_assert.hh>
#include <dune/common/timer.hh>
#include <dune/common/dynvector.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/discretefunction/projection/dirichlet.hh>

#include <dune/detailed/discretizations/space/continuouslagrange/fem.hh>
#include <dune/detailed/discretizations/la/containerfactory/eigen.hh>
#include <dune/detailed/discretizations/localevaluation/elliptic.hh>
#include <dune/detailed/discretizations/localevaluation/product.hh>
#include <dune/detailed/discretizations/localoperator/codim0.hh>
#include <dune/detailed/discretizations/localfunctional/codim0.hh>
#include <dune/detailed/discretizations/assembler/local/codim0.hh>
#include <dune/detailed/discretizations/space/constraints.hh>
#include <dune/detailed/discretizations/assembler/system.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>

const std::string id = "elliptic.continuousgalerkin";

#ifndef POLORDER
const int polOrder = 1;
#else
const int polOrder = POLORDER;
#endif
dune_static_assert((polOrder > 0), "ERROR: polOrder hast to be positive!");

using namespace Dune::Detailed::Discretizations;

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(const std::string& filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "grid = "
         << "gridprovider.cube" << std::endl;
    file << "boundaryinfo = "
         << "boundaryinfo.alldirichlet" << std::endl;
    file << "[gridprovider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = [12; 12; 12]" << std::endl;
    file << "[boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 2; 3]" << std::endl;
    file << "neumann = [4]" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.1*x[0]; 0.0; 0.0]" << std::endl;
    file << "[neumann]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "type = bicgstab.ilut" << std::endl;
    file << "maxIter = 5000" << std::endl;
    file << "precision = 1e-12" << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::Fem::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".description";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree description(argc, argv, paramFilename);
    description.assertSub(id);

    // logger
    Dune::Stuff::Common::Logger().create(Dune::Stuff::Common::LOG_INFO | Dune::Stuff::Common::LOG_CONSOLE);
    Dune::Stuff::Common::LogStream& info = Dune::Stuff::Common::Logger().info();

    // timer
    Dune::Timer timer;

    info << "setting up grid:" << std::endl;
    typedef Dune::Stuff::GridProviderInterface<> GridProviderType;
    const GridProviderType* gridProvider =
        Dune::Stuff::GridProviders<>::create(description.get(id + ".grid", "gridprovider.cube"), description);
    typedef GridProviderType::GridType GridType;
    const std::shared_ptr<const GridType> grid = gridProvider->grid();
    typedef Dune::grid::Part::Leaf::Const<GridType> GridPartType;
    typedef typename GridPartType::GridViewType GridViewType;
    const GridPartType gridPart(*grid);
    typedef typename Dune::Stuff::GridboundaryInterface<typename GridPartType::GridViewType> BoundaryInfoType;
    const std::shared_ptr<const BoundaryInfoType> boundaryInfo(
        Dune::Stuff::Gridboundaries<typename GridPartType::GridViewType>::create(
            description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"), description));
    info << "  took " << timer.elapsed() << " sec, has " << grid->size(0) << " entities" << std::endl;
    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"),
                            description,
                            description.get(id + ".filename", id) + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    const unsigned int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const unsigned int DUNE_UNUSED(dimRange) = 1;
    typedef typename GridType::ctype DomainFieldType;
    typedef double RangeFieldType;

    typedef Dune::Stuff::FunctionExpression<DomainFieldType, dimDomain, RangeFieldType, dimRange>
        ExpressionFunctionType;
    const std::shared_ptr<const ExpressionFunctionType> diffusion(
        ExpressionFunctionType::create(description.sub("diffusion")));
    const std::shared_ptr<const ExpressionFunctionType> force(ExpressionFunctionType::create(description.sub("force")));
    const std::shared_ptr<const ExpressionFunctionType> dirichlet(
        ExpressionFunctionType::create(description.sub("dirichlet")));
    const std::shared_ptr<const ExpressionFunctionType> neumann(
        ExpressionFunctionType::create(description.sub("neumann")));

    info << "initializing discrete function spaces... " << std::flush;
    timer.reset();
    typedef ContinuousLagrangeSpace::FemWrapper<GridPartType, polOrder, RangeFieldType, dimRange> SpaceType;
    const SpaceType space(gridPart);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // left hand side
    // * elliptic diffusion operator
    typedef LocalOperator::Codim0Integral<LocalEvaluation::Elliptic, ExpressionFunctionType> EllipticOperatorType;
    const EllipticOperatorType diffusionOperator(*diffusion);
    // * right hand side
    //   * L2 force functional
    typedef LocalFunctional::Codim0Integral<LocalEvaluation::Product, ExpressionFunctionType> L2FunctionalType;
    const L2FunctionalType forceFunctional(*force);
    //   * L2 neumann functional
    const L2FunctionalType neumannFunctional(*neumann);

    info << "initializing matrix (of size " << space.mapper().size() << "x" << space.mapper().size()
         << ") and vectors... " << std::flush;
    timer.reset();
    typedef ContainerFactoryEigen<RangeFieldType> ContainerFactory;
    typedef ContainerFactory::RowMajorSparseMatrixType MatrixType;
    typedef ContainerFactory::DenseVectorType VectorType;
    std::shared_ptr<MatrixType> systemMatrix(ContainerFactory::createRowMajorSparseMatrix(space, space));
    std::shared_ptr<VectorType> forceVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> dirichletVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> neumannVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> rhsVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> solutionVector(ContainerFactory::createDenseVector(space));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "assembing system... " << std::flush;
    timer.reset();
    // * dirichlet boundary values
    typedef DiscreteFunctionDefault<SpaceType, VectorType> DiscreteFunctionType;
    DiscreteFunctionType dirichletProjection(space, dirichletVector, "dirichlet");
    Dune::Stuff::DiscreteFunction::project(*boundaryInfo, *dirichlet, dirichletProjection);

    // * local matrix assembler
    typedef LocalAssembler::Codim0Matrix<EllipticOperatorType> LocalEllipticOperatorMatrixAssemblerType;
    const LocalEllipticOperatorMatrixAssemblerType diffusionMatrixAssembler(diffusionOperator);
    // * local vector assemblers
    typedef LocalAssembler::Codim0Vector<L2FunctionalType> LocalL2FunctionalVectorAssemblerType;
    //   * force vector
    const LocalL2FunctionalVectorAssemblerType forceVectorAssembler(forceFunctional);
    //   * neumann vector
    const LocalL2FunctionalVectorAssemblerType neumannVectorAssembler(neumannFunctional);
    // * system assembler
    typedef SystemAssembler<SpaceType, SpaceType> SystemAssemblerType;
    SystemAssemblerType systemAssembler(space);
    systemAssembler.addLocalMatrixAssembler(diffusionMatrixAssembler, *systemMatrix);
    systemAssembler.addLocalVectorAssembler(forceVectorAssembler, *forceVector);
    systemAssembler.addLocalVectorAssembler(neumannVectorAssembler, *neumannVector);
    systemAssembler.assemble();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "applying constraints... " << std::flush;
    timer.reset();
    Constraints::Dirichlet<GridViewType, RangeFieldType> dirichletConstraints(
        *boundaryInfo, space.mapper().maxNumDofs(), space.mapper().maxNumDofs());
    rhsVector->backend() =
        forceVector->backend() + neumannVector->backend() - systemMatrix->backend() * dirichletVector->backend();
    systemAssembler.applyConstraints(dirichletConstraints, *systemMatrix, *rhsVector);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "solving linear system (of size " << systemMatrix->rows() << "x" << systemMatrix->cols() << ")"
         << std::endl;
    const std::string solverType     = description.get("solver.type", "bicgstab");
    const unsigned int solverMaxIter = description.get("solver.maxIter", 5000);
    const double solverPrecision     = description.get("solver.precision", 1e-12);
    info << "  using '" << solverType << "'... " << std::flush;
    timer.reset();
    typedef typename Dune::Stuff::LA::Solver::Interface<MatrixType, VectorType> SolverType;
    std::shared_ptr<SolverType> solver(Dune::Stuff::LA::Solver::create<MatrixType, VectorType>(solverType));
    const unsigned int failure =
        solver->apply(*systemMatrix, *rhsVector, *solutionVector, solverMaxIter, solverPrecision);
    if (failure)
      DUNE_THROW(Dune::MathError, "\nERROR: linear solver '" << solverType << "' reported a problem!");
    if (solutionVector->size() != space.mapper().size())
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' produced a solution of wrong size (is "
                                            << solutionVector->size()
                                            << ", should be "
                                            << space.mapper().size()
                                            << ")!");
    solutionVector->backend() += dirichletVector->backend();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    const std::string solutionFilename = description.get(id + ".filename", id) + ".solution";
    const std::string solutionName     = id + ".solution";
    info << "writing solution to '" << solutionFilename;
    if (dimDomain == 1)
      info << ".vtp";
    else
      info << ".vtu";
    info << "'... " << std::flush;
    timer.reset();
    typedef DiscreteFunctionDefaultConst<SpaceType, VectorType> ConstDiscreteFunctionType;
    const std::shared_ptr<const ConstDiscreteFunctionType> solution(
        new ConstDiscreteFunctionType(space, solutionVector, solutionName));
    typedef Dune::VTKWriter<GridViewType> VTKWriterType;
    VTKWriterType vtkWriter(gridPart.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<|endoftext|>


<commit_before>/// Project specific
// This class
#include <Manager/PressureParticleManager.hpp>
// Handlers
#include <EntityComponent/EntityHandler.hpp>
// Components
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/PressureParticleComponent.hpp>
#include <EntityComponent/Components/RenderComponent.hpp>

/// Engine
// Physics
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/FluidManager.hpp>
// Render
#include <DoremiEngine/Graphic/Include/GraphicModule.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Manager/MeshManager.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Manager/DirectXManager.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Manager/SubModuleManager.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Mesh/MeshInfo.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Mesh/MaterialInfo.hpp>

// 3rd party
#include <DirectXMath.h>

#include <stdint.h>

using namespace DirectX;
namespace Doremi
{
    namespace Core
    {
        PressureParticleManager::PressureParticleManager(const DoremiEngine::Core::SharedContext& p_sharedContext)
            : Manager(p_sharedContext, "PreasureParticleManager")
        {
        }
        PressureParticleManager::~PressureParticleManager() {}

        void PressureParticleManager::Update(double p_dt)
        {
            int derp = 5;
            static int frame = 0;
            frame++;
            size_t length = EntityHandler::GetInstance().GetLastEntityIndex();
            int mask = (int)ComponentType::Transform || (int)ComponentType::PressureParticleSystem;

            RenderComponent* renderComp = EntityHandler::GetInstance().GetComponentFromStorage<RenderComponent>(14);
            DirectX::XMFLOAT4X4 transMat;
            DirectX::XMMATRIX tempTransMat = DirectX::XMMatrixTranspose(DirectX::XMMatrixTranslation(5, 5, 5));
            DirectX::XMStoreFloat4x4(&transMat, tempTransMat);
            m_sharedContext.GetGraphicModule().GetSubModuleManager().GetMeshManager().AddToRenderList(*renderComp->mesh, *renderComp->material, transMat);

            for(size_t i = 0; i < length; i++)
            {
                if(EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::Transform) &&
                   EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::PressureParticleSystem) &&
                   EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::Render))
                {
                    // Read thingies
                    vector<XMFLOAT3> returnPositions;
                    m_sharedContext.GetPhysicsModule().GetFluidManager().GetParticlePositions(i, returnPositions);

                    // Render thingies
                    RenderComponent* renderComp = EntityHandler::GetInstance().GetComponentFromStorage<RenderComponent>(i);
                    for(size_t j = 0; j < returnPositions.size(); j++)
                    {
                        DirectX::XMFLOAT4X4 transMat;
                        DirectX::XMMATRIX tempTransMat =
                            DirectX::XMMatrixTranspose(DirectX::XMMatrixTranslation(returnPositions[j].x, returnPositions[j].y, returnPositions[j].z));
                        DirectX::XMStoreFloat4x4(&transMat, tempTransMat);
                        m_sharedContext.GetGraphicModule().GetSubModuleManager().GetMeshManager().AddToRenderList(*renderComp->mesh, *renderComp->material, transMat);
                    }
                }
            }
        }

        void PressureParticleManager::OnEvent(Event* p_event) {}
    }
}<commit_msg>ParticleGraphic: Manager now draws mesh and material of particles<commit_after>/// Project specific
// This class
#include <Manager/PressureParticleManager.hpp>
// Handlers
#include <EntityComponent/EntityHandler.hpp>
// Components
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/PressureParticleComponent.hpp>
#include <EntityComponent/Components/RenderComponent.hpp>

/// Engine
// Physics
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/FluidManager.hpp>
// Render
#include <DoremiEngine/Graphic/Include/GraphicModule.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Manager/MeshManager.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Manager/DirectXManager.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Manager/SubModuleManager.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Mesh/MeshInfo.hpp>
#include <DoremiEngine/Graphic/Include/Interface/Mesh/MaterialInfo.hpp>

// 3rd party
#include <DirectXMath.h>

#include <stdint.h>

using namespace DirectX;
namespace Doremi
{
    namespace Core
    {
        PressureParticleManager::PressureParticleManager(const DoremiEngine::Core::SharedContext& p_sharedContext)
            : Manager(p_sharedContext, "PreasureParticleManager")
        {
        }
        PressureParticleManager::~PressureParticleManager() {}

        void PressureParticleManager::Update(double p_dt)
        {
            int derp = 5;
            static int frame = 0;
            frame++;
            size_t length = EntityHandler::GetInstance().GetLastEntityIndex();
            int mask = (int)ComponentType::Transform || (int)ComponentType::PressureParticleSystem;

            RenderComponent* renderComp = EntityHandler::GetInstance().GetComponentFromStorage<RenderComponent>(14);
            DirectX::XMFLOAT4X4 transMat;
            DirectX::XMMATRIX tempTransMat = DirectX::XMMatrixTranspose(DirectX::XMMatrixTranslation(5, 5, 5));
            DirectX::XMStoreFloat4x4(&transMat, tempTransMat);
            m_sharedContext.GetGraphicModule().GetSubModuleManager().GetMeshManager().AddToRenderList(*renderComp->mesh, *renderComp->material, transMat);

            for(size_t i = 0; i < length; i++)
            {
                if(EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::Transform) &&
                   EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::PressureParticleSystem) &&
                   EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::Render))
                {
                    // Read thingies
                    vector<XMFLOAT3> returnPositions;
                    m_sharedContext.GetPhysicsModule().GetFluidManager().GetParticlePositions(i, returnPositions);
                    ParticlePressureComponent* particleComp = EntityHandler::GetInstance().GetComponentFromStorage<ParticlePressureComponent>(i);

                    // Render thingies
                    RenderComponent* renderComp = EntityHandler::GetInstance().GetComponentFromStorage<RenderComponent>(i);
                    for(size_t j = 0; j < returnPositions.size(); j++)
                    {
                        DirectX::XMFLOAT4X4 transMat;
                        DirectX::XMMATRIX tempTransMat =
                            DirectX::XMMatrixTranspose(DirectX::XMMatrixTranslation(returnPositions[j].x, returnPositions[j].y, returnPositions[j].z));
                        DirectX::XMStoreFloat4x4(&transMat, tempTransMat);
                        m_sharedContext.GetGraphicModule().GetSubModuleManager().GetMeshManager().AddToRenderList(*particleComp->mesh,
                                                                                *particleComp->material, transMat);
                    }
                }
            }
        }

        void PressureParticleManager::OnEvent(Event* p_event) {}
    }
}<|endoftext|>


<commit_before>#ifndef __STAN__AGRAD__AGRAD_HPP__
#define __STAN__AGRAD__AGRAD_HPP__

#include <stan/agrad/rev/var_stack.hpp>
#include <stan/agrad/rev/chainable.hpp>
#include <stan/agrad/rev/vari.hpp>
#include <stan/agrad/rev/var.hpp>
#include <stan/agrad/rev/print_stack.hpp>

#include <stan/agrad/rev/op/v_vari.hpp>
#include <stan/agrad/rev/op/vv_vari.hpp>
#include <stan/agrad/rev/op/vd_vari.hpp>
#include <stan/agrad/rev/op/dv_vari.hpp>
#include <stan/agrad/rev/op/vvv_vari.hpp>
#include <stan/agrad/rev/op/vvd_vari.hpp>
#include <stan/agrad/rev/op/vdv_vari.hpp>
#include <stan/agrad/rev/op/vdd_vari.hpp>
#include <stan/agrad/rev/op/dvv_vari.hpp>
#include <stan/agrad/rev/op/dvd_vari.hpp>
#include <stan/agrad/rev/op/ddv_vari.hpp>
#include <stan/agrad/rev/precomp_v_vari.hpp>

#include <stan/agrad/rev/operator_unary_negative.hpp>
#include <stan/agrad/rev/operator_equal.hpp>
#include <stan/agrad/rev/operator_not_equal.hpp>
#include <stan/agrad/rev/operator_greater_than.hpp>
#include <stan/agrad/rev/operator_greater_than_or_equal.hpp>
#include <stan/agrad/rev/operator_less_than.hpp>
#include <stan/agrad/rev/operator_less_than_or_equal.hpp>
#include <stan/agrad/rev/operator_unary_not.hpp>
#include <stan/agrad/rev/operator_unary_plus.hpp>
#include <stan/agrad/rev/operator_addition.hpp>
#include <stan/agrad/rev/operator_subtraction.hpp>
#include <stan/agrad/rev/operator_multiplication.hpp>
#include <stan/agrad/rev/operator_division.hpp>
#include <stan/agrad/rev/operator_unary_increment.hpp>
#include <stan/agrad/rev/operator_unary_decrement.hpp>

#include <stan/agrad/rev/exp.hpp>
#include <stan/agrad/rev/log.hpp>
#include <stan/agrad/rev/log10.hpp>
#include <stan/agrad/rev/sqrt.hpp>
#include <stan/agrad/rev/pow.hpp>
#include <stan/agrad/rev/cos.hpp>
#include <stan/agrad/rev/sin.hpp>
#include <stan/agrad/rev/tan.hpp>
#include <stan/agrad/rev/acos.hpp>
#include <stan/agrad/rev/asin.hpp>
#include <stan/agrad/rev/atan.hpp>
#include <stan/agrad/rev/atan2.hpp>
#include <stan/agrad/rev/cosh.hpp>
#include <stan/agrad/rev/sinh.hpp>
#include <stan/agrad/rev/tanh.hpp>
#include <stan/agrad/rev/fabs.hpp>
#include <stan/agrad/rev/floor.hpp>
#include <stan/agrad/rev/ceil.hpp>
#include <stan/agrad/rev/fmod.hpp>
#include <stan/agrad/rev/abs.hpp>
#include <stan/agrad/rev/jacobian.hpp>

#include <stan/agrad/rev/operator_plus_equal.hpp>
#include <stan/agrad/rev/operator_minus_equal.hpp>
#include <stan/agrad/rev/operator_multiply_equal.hpp>
#include <stan/agrad/rev/operator_divide_equal.hpp>

#include <stan/agrad/rev/numeric_limits.hpp>
#include <stan/agrad/rev/is_uninitialized.hpp>

#include <stan/agrad/rev/acosh.hpp>
#include <stan/agrad/rev/atanh.hpp>
#include <stan/agrad/rev/asinh.hpp>
#include <stan/agrad/rev/erf.hpp>
#include <stan/agrad/rev/erfc.hpp>
#include <stan/agrad/rev/exp2.hpp>
#include <stan/agrad/rev/expm1.hpp>
#include <stan/agrad/rev/lgamma.hpp>
#include <stan/agrad/rev/log1p.hpp>
#include <stan/agrad/rev/log1m.hpp>
#include <stan/agrad/rev/fma.hpp>
#include <stan/agrad/rev/fmax.hpp>
#include <stan/agrad/rev/fmin.hpp>
#include <stan/agrad/rev/hypot.hpp>
#include <stan/agrad/rev/log2.hpp>
#include <stan/agrad/rev/cbrt.hpp>
#include <stan/agrad/rev/round.hpp>
#include <stan/agrad/rev/trunc.hpp>
#include <stan/agrad/rev/fdim.hpp>

#endif
<commit_msg>splitting tgamma out of agrad/special_functions.hpp<commit_after>#ifndef __STAN__AGRAD__AGRAD_HPP__
#define __STAN__AGRAD__AGRAD_HPP__

#include <stan/agrad/rev/var_stack.hpp>
#include <stan/agrad/rev/chainable.hpp>
#include <stan/agrad/rev/vari.hpp>
#include <stan/agrad/rev/var.hpp>
#include <stan/agrad/rev/print_stack.hpp>

#include <stan/agrad/rev/op/v_vari.hpp>
#include <stan/agrad/rev/op/vv_vari.hpp>
#include <stan/agrad/rev/op/vd_vari.hpp>
#include <stan/agrad/rev/op/dv_vari.hpp>
#include <stan/agrad/rev/op/vvv_vari.hpp>
#include <stan/agrad/rev/op/vvd_vari.hpp>
#include <stan/agrad/rev/op/vdv_vari.hpp>
#include <stan/agrad/rev/op/vdd_vari.hpp>
#include <stan/agrad/rev/op/dvv_vari.hpp>
#include <stan/agrad/rev/op/dvd_vari.hpp>
#include <stan/agrad/rev/op/ddv_vari.hpp>
#include <stan/agrad/rev/precomp_v_vari.hpp>

#include <stan/agrad/rev/operator_unary_negative.hpp>
#include <stan/agrad/rev/operator_equal.hpp>
#include <stan/agrad/rev/operator_not_equal.hpp>
#include <stan/agrad/rev/operator_greater_than.hpp>
#include <stan/agrad/rev/operator_greater_than_or_equal.hpp>
#include <stan/agrad/rev/operator_less_than.hpp>
#include <stan/agrad/rev/operator_less_than_or_equal.hpp>
#include <stan/agrad/rev/operator_unary_not.hpp>
#include <stan/agrad/rev/operator_unary_plus.hpp>
#include <stan/agrad/rev/operator_addition.hpp>
#include <stan/agrad/rev/operator_subtraction.hpp>
#include <stan/agrad/rev/operator_multiplication.hpp>
#include <stan/agrad/rev/operator_division.hpp>
#include <stan/agrad/rev/operator_unary_increment.hpp>
#include <stan/agrad/rev/operator_unary_decrement.hpp>

#include <stan/agrad/rev/exp.hpp>
#include <stan/agrad/rev/log.hpp>
#include <stan/agrad/rev/log10.hpp>
#include <stan/agrad/rev/sqrt.hpp>
#include <stan/agrad/rev/pow.hpp>
#include <stan/agrad/rev/cos.hpp>
#include <stan/agrad/rev/sin.hpp>
#include <stan/agrad/rev/tan.hpp>
#include <stan/agrad/rev/acos.hpp>
#include <stan/agrad/rev/asin.hpp>
#include <stan/agrad/rev/atan.hpp>
#include <stan/agrad/rev/atan2.hpp>
#include <stan/agrad/rev/cosh.hpp>
#include <stan/agrad/rev/sinh.hpp>
#include <stan/agrad/rev/tanh.hpp>
#include <stan/agrad/rev/fabs.hpp>
#include <stan/agrad/rev/floor.hpp>
#include <stan/agrad/rev/ceil.hpp>
#include <stan/agrad/rev/fmod.hpp>
#include <stan/agrad/rev/abs.hpp>
#include <stan/agrad/rev/jacobian.hpp>

#include <stan/agrad/rev/operator_plus_equal.hpp>
#include <stan/agrad/rev/operator_minus_equal.hpp>
#include <stan/agrad/rev/operator_multiply_equal.hpp>
#include <stan/agrad/rev/operator_divide_equal.hpp>

#include <stan/agrad/rev/numeric_limits.hpp>
#include <stan/agrad/rev/is_uninitialized.hpp>

#include <stan/agrad/rev/acosh.hpp>
#include <stan/agrad/rev/atanh.hpp>
#include <stan/agrad/rev/asinh.hpp>
#include <stan/agrad/rev/erf.hpp>
#include <stan/agrad/rev/erfc.hpp>
#include <stan/agrad/rev/exp2.hpp>
#include <stan/agrad/rev/expm1.hpp>
#include <stan/agrad/rev/lgamma.hpp>
#include <stan/agrad/rev/log1p.hpp>
#include <stan/agrad/rev/log1m.hpp>
#include <stan/agrad/rev/fma.hpp>
#include <stan/agrad/rev/fmax.hpp>
#include <stan/agrad/rev/fmin.hpp>
#include <stan/agrad/rev/hypot.hpp>
#include <stan/agrad/rev/log2.hpp>
#include <stan/agrad/rev/cbrt.hpp>
#include <stan/agrad/rev/round.hpp>
#include <stan/agrad/rev/trunc.hpp>
#include <stan/agrad/rev/fdim.hpp>
#include <stan/agrad/rev/tgamma.hpp>

#endif
<|endoftext|>


<commit_before>// Copyright 2013-2015 Stanford University
//
// Licensed under the Apache License, Version 2.0 (the License);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/stategen/stategen.h"

#include <cstdlib>

#include "src/sandbox/sandbox.h"
#include "src/sandbox/state_callback.h"
#include "src/state/regs.h"

using namespace stoke;
using namespace x64asm;

namespace {

void callback(const StateCallbackData& data, void* arg) {
  Instruction& last_line = *((Instruction*) arg);
  last_line = data.code[data.line];
}

} // namespace

namespace stoke {

bool StateGen::get(CpuState& cs) const {
  // Randomize registers
  for (size_t i = 0, ie = cs.gp.size(); i < ie; ++i) {
    auto& r = cs.gp[i];
    for (size_t j = 0, je = r.num_fixed_bytes(); j < je; ++j) {
      r.get_fixed_byte(j) = rand() % 256;
    }
  }
  for (size_t i = 0, ie = cs.sse.size(); i < ie; ++i) {
    auto& s = cs.sse[i];
    for (size_t j = 0, je = s.num_fixed_bytes(); j < je; ++j) {
      s.get_fixed_byte(j) = rand() % 256;
    }
  }
  for (size_t i = 0, ie = cs.rf.size(); i < ie; ++i) {
    if (!cs.rf.is_fixed(i)) {
      cs.rf.set(i, rand() % 2);
    }
  }

  // Map rsp to a high address
  cs.gp[rsp].get_fixed_quad(0) = 0x700000000;

  // Generate default memory
  cs.stack.resize(cs.gp[rsp].get_fixed_quad(0) - stack_size_, stack_size_);
  cs.heap.resize(0x100000000, 0);
  cs.data.resize(0x000000000, 0);
  randomize_mem(cs.stack);

  // Set up symbol table beginning at the bottom of the address space
  cs.sym_table.clear();
  uint64_t addr = 0x00400000;

  for (auto i = sb_->function_begin(), ie = sb_->function_end(); i != ie; ++i) {
    const auto& l = i->get_code()[0].get_operand<Label>(0).get_text();
    cs.sym_table.insert(l, addr);
    addr += 16 * i->get_code().size();
  }

  return true;
}

bool StateGen::get(CpuState& cs, const Cfg& cfg) {
  // Insert callbacks before every instruction and compile
  Instruction last_line(RET);
  sb_->clear_callbacks();
  sb_->insert_before(callback, (void*)&last_line);
  sb_->compile(cfg);

  // Generate a random state and keep checking for validity
  get(cs);
  tried_to_fix_misalign_ = false;
  for (int i = 0; i < (int)max_attempts_; ++i) {
    // Reset the sandbox state and try executing
    sb_->clear_inputs();
    sb_->insert_input(cs);
    sb_->run_one(0);

    // There's a single failure case we have to deal with immediately.
    // If the sandbox couldn't link cfg against its aux functions, it
    // won't ever run and set the value of last_line.
    if (sb_->get_result(0)->code == ErrorCode::SIGBUS_) {
      error_message_ = "Linking failed!";
      return false;
    }

    // If we didn't segfault, or we did due to misalign and it's allowed,
    // then we're done
    if(is_ok(*sb_, last_line)) {
      return true;
    }
    // Otherwise, try allocating away a segfault and retry
    else if (fix(*(sb_->get_result(0)), cs, last_line)) {
      i--;
    }
    // Otherwise, generate a new state and call this attempt failed
    else {
      get(cs);
      tried_to_fix_misalign_ = false;
    }
  }

  return false;
}

bool StateGen::is_ok(const Sandbox& sb, const Instruction& line) {
  if (sb_->get_result(0)->code == ErrorCode::NORMAL) {
    return true;
  }

  if(!is_supported_deref(line))
    return false;

  CpuState cs = *(sb_->get_result(0));
  const auto addr = get_addr(cs, line);
  const auto size = get_size(line);

  // If the address is already allocated, there's a segfault,
  // it's misaligned and we allow misaligned, then we're ok.
  if(allow_unaligned_ && is_misaligned(addr, size) &&
      cs.code == ErrorCode::SIGSEGV_ &&
      (already_allocated(cs.stack, addr, size) ||
       already_allocated(cs.heap, addr, size))) {
    return true;
  }

  return false;
}

bool StateGen::is_supported_deref(const Instruction& instr) {
  // Special support for push/pop/ret
  if (instr.is_push() || instr.is_pop() || instr.is_any_return() || instr.is_call()) {
    return true;
  }

  // No support for implicit memory accesses
  if (instr.is_implicit_memory_dereference()) {
    error_message_ = "Implicit memory dereferences not supported.";
    return false;
  }

  if (instr.mem_index() == -1) {
    error_message_ = "Could not find an explicit or implicit memory dereference."
                     "  Bug somewhere (forgot retq?).";
    return false;
  }

  const auto mi = instr.mem_index();
  const auto op = instr.get_operand<M8>(mi);

  // No support for rip-offset form or segment register addressing
  if (op.rip_offset() || op.contains_seg()) {
    error_message_ = "No support for RIP offset or segment addressing";
    return false;
  }

  return true;
}

uint64_t StateGen::get_addr(const CpuState& cs, const Instruction& instr) const {
  // Special handling for implicit dereferences
  if (instr.is_push() || instr.is_call()) {
    return cs.gp[rsp].get_fixed_quad(0) - 8;
  } else if (instr.is_pop()) {
    return cs.gp[rsp].get_fixed_quad(0);
  } else if (instr.is_any_return()) {
    return cs.gp[rsp].get_fixed_quad(0);
  }

  const auto mi = instr.mem_index();
  const auto op = instr.get_operand<M8>(mi);

  uint64_t addr = 0;
  if (op.contains_base()) {
    if (op.addr_or()) {
      addr += cs.gp[op.get_base()].get_fixed_double(0);
    } else {
      addr += cs.gp[op.get_base()].get_fixed_quad(0);
    }
  }
  if (op.contains_index()) {
    auto scale = 1;
    switch (op.get_scale()) {
    case Scale::TIMES_2:
      scale = 2;
      break;
    case Scale::TIMES_4:
      scale = 4;
      break;
    case Scale::TIMES_8:
      scale = 8;
      break;
    default:
      scale = 1;
      break;
    }

    if (op.addr_or()) {
      addr += (scale * cs.gp[op.get_index()].get_fixed_double(0));
    } else {
      addr += (scale * cs.gp[op.get_index()].get_fixed_quad(0));
    }
  }

  /* We need to sign-extend the displacement from 32 to 64 bits */
  uint64_t displacement = (op.get_disp());
  if (displacement & 0x80000000) {
    displacement |= 0xffffffff00000000;
  }
  addr += displacement;

  return addr;
}

size_t StateGen::get_size(const Instruction& instr) const {
  // Special handling for implicit dereferences
  if (instr.is_push() || instr.is_pop() || instr.is_any_return() || instr.is_call()) {
    return 8;
  }

  // Otherwise, we can infer width from type
  const auto mi = instr.mem_index();
  return instr.get_operand<M8>(mi).size()/8;
}

bool StateGen::resize_within(Memory& mem, uint64_t addr, size_t size) const {
  // This should always be true, otherwise there'd be no work to do
  // * See the previous check against already_allocated() one level up
  assert((addr + size) > mem.upper_bound());

  const auto delta = addr + size - mem.upper_bound();
  if (mem.size() + delta > max_memory_) {
    return false;
  }

  mem.resize(mem.lower_bound(), mem.size() + delta);
  randomize_mem(mem);
  return true;
}

bool StateGen::resize_below(Memory& mem, uint64_t addr, size_t size) const {
  size_t new_size = 0;
  if (addr + size > mem.upper_bound()) {
    new_size = size;
  } else {
    new_size = mem.upper_bound() - addr;
  }

  if (new_size > max_memory_) {
    return false;
  }

  mem.resize(addr, new_size);
  randomize_mem(mem);
  return true;
}

bool StateGen::resize_above(Memory& mem, uint64_t addr, size_t size) const {
  const auto delta = addr + size - mem.upper_bound();
  if (mem.size() + delta > max_memory_) {
    return false;
  }

  mem.resize(mem.lower_bound(), mem.size() + delta);
  randomize_mem(mem);
  return true;
}

void StateGen::randomize_mem(Memory& mem) const {
  for (auto i = mem.lower_bound(), ie = mem.upper_bound(); i < ie; ++i) {
    if (!mem.is_valid(i)) {
      mem.set_valid(i, true);
      mem[i] = rand() % 256;
    }
  }
}

bool StateGen::resize_mem(Memory& mem, uint64_t addr, size_t size) const {
  if (mem.size() == 0) {
    mem.resize(addr, size);
    randomize_mem(mem);
    return true;
  } else if (mem.in_range(addr) && resize_within(mem, addr, size)) {
    return true;
  } else if (addr < mem.lower_bound() && resize_below(mem, addr, size)) {
    return true;
  } else if (addr >= mem.upper_bound() && resize_above(mem, addr, size)) {
    return true;
  } else {
    return false;
  }
}

bool StateGen::fix_misalignment(const CpuState& cs, CpuState& fixed, const Instruction& instr) {
  const auto mi = instr.mem_index();
  const auto op = instr.get_operand<M8>(mi);

  const auto addr = get_addr(cs, instr);
  const auto mask = 0x1f;
  const auto offset = addr & mask;

  if (op.contains_base()) {
    const auto current = cs.gp[op.get_base()].get_fixed_quad(0);
    if(((current - offset) & mask) && !tried_to_fix_misalign_) {
      const auto new_byte = (current & mask) - offset;
      fixed.gp[op.get_base()].get_fixed_byte(0) = new_byte;
      tried_to_fix_misalign_ = true;
      return true;
    } else {
      error_message_ = "Could not fix misaligned memory reference.";
      tried_to_fix_misalign_ = false;
      return false;
    }
  } else {
    error_message_ = "Could not find misaligned memory reference.";
    tried_to_fix_misalign_ = false;
    return false;
  }

}

bool StateGen::fix(const CpuState& cs, CpuState& fixed, const Instruction& instr) {
  // Clear the error message unless something bad happens.
  error_message_ = "";

  // Only sigsegv is fixable
  if (cs.code != ErrorCode::SIGSEGV_) {
    error_message_ = "Interrupt was not segfault.";
    return false;
  }
  // Only explicit dereferences are fixable
  if (!is_supported_deref(instr)) {
    return false;
  }

  const auto addr = get_addr(cs, instr);
  const auto size = get_size(instr);

  // We can't do anything about misaligned memory or pre-allocated memory
  if (is_misaligned(addr, size) && !allow_unaligned_) {
    return fix_misalignment(cs, fixed, instr);
  } else if (already_allocated(fixed.stack, addr, size)) {
    tried_to_fix_misalign_ = false;
    error_message_ = "Memory was already allocated in stack.";
    return false;
  } else if (already_allocated(fixed.heap, addr, size)) {
    tried_to_fix_misalign_ = false;
    error_message_ = "Memory was already allocated in heap.";
    return false;
  }

  // If we can't resize stack or heap, give up.
  if (!resize_mem(fixed.stack, addr, size) && !resize_mem(fixed.heap, addr, size)) {
    error_message_ = "Could not resize memory.";
    return false;
  }

  // If stack and heap overlap now, give up. This memory is broken.
  if (!(fixed.heap.upper_bound() < fixed.stack.lower_bound() ||
        fixed.stack.upper_bound() < fixed.heap.lower_bound())) {
    error_message_ = "Heap and stack overlap.";
    return false;
  }

  // Look like we did something right. Return success.
  return true;
}

} // namespace stoke
<commit_msg>more precise error message<commit_after>// Copyright 2013-2015 Stanford University
//
// Licensed under the Apache License, Version 2.0 (the License);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/stategen/stategen.h"

#include <cstdlib>
#include <string>

#include "src/sandbox/sandbox.h"
#include "src/sandbox/state_callback.h"
#include "src/state/regs.h"

using namespace stoke;
using namespace x64asm;

namespace {

void callback(const StateCallbackData& data, void* arg) {
  Instruction& last_line = *((Instruction*) arg);
  last_line = data.code[data.line];
}

} // namespace

namespace stoke {

bool StateGen::get(CpuState& cs) const {
  // Randomize registers
  for (size_t i = 0, ie = cs.gp.size(); i < ie; ++i) {
    auto& r = cs.gp[i];
    for (size_t j = 0, je = r.num_fixed_bytes(); j < je; ++j) {
      r.get_fixed_byte(j) = rand() % 256;
    }
  }
  for (size_t i = 0, ie = cs.sse.size(); i < ie; ++i) {
    auto& s = cs.sse[i];
    for (size_t j = 0, je = s.num_fixed_bytes(); j < je; ++j) {
      s.get_fixed_byte(j) = rand() % 256;
    }
  }
  for (size_t i = 0, ie = cs.rf.size(); i < ie; ++i) {
    if (!cs.rf.is_fixed(i)) {
      cs.rf.set(i, rand() % 2);
    }
  }

  // Map rsp to a high address
  cs.gp[rsp].get_fixed_quad(0) = 0x700000000;

  // Generate default memory
  cs.stack.resize(cs.gp[rsp].get_fixed_quad(0) - stack_size_, stack_size_);
  cs.heap.resize(0x100000000, 0);
  cs.data.resize(0x000000000, 0);
  randomize_mem(cs.stack);

  // Set up symbol table beginning at the bottom of the address space
  cs.sym_table.clear();
  uint64_t addr = 0x00400000;

  for (auto i = sb_->function_begin(), ie = sb_->function_end(); i != ie; ++i) {
    const auto& l = i->get_code()[0].get_operand<Label>(0).get_text();
    cs.sym_table.insert(l, addr);
    addr += 16 * i->get_code().size();
  }

  return true;
}

bool StateGen::get(CpuState& cs, const Cfg& cfg) {
  // Insert callbacks before every instruction and compile
  Instruction last_line(RET);
  sb_->clear_callbacks();
  sb_->insert_before(callback, (void*)&last_line);
  sb_->compile(cfg);

  // Generate a random state and keep checking for validity
  get(cs);
  tried_to_fix_misalign_ = false;
  for (int i = 0; i < (int)max_attempts_; ++i) {
    // Reset the sandbox state and try executing
    sb_->clear_inputs();
    sb_->insert_input(cs);
    sb_->run_one(0);

    // There's a single failure case we have to deal with immediately.
    // If the sandbox couldn't link cfg against its aux functions, it
    // won't ever run and set the value of last_line.
    if (sb_->get_result(0)->code == ErrorCode::SIGBUS_) {
      error_message_ = "Linking failed!";
      return false;
    }

    // If we didn't segfault, or we did due to misalign and it's allowed,
    // then we're done
    if(is_ok(*sb_, last_line)) {
      return true;
    }
    // Otherwise, try allocating away a segfault and retry
    else if (fix(*(sb_->get_result(0)), cs, last_line)) {
      i--;
    }
    // Otherwise, generate a new state and call this attempt failed
    else {
      get(cs);
      tried_to_fix_misalign_ = false;
    }
  }

  return false;
}

bool StateGen::is_ok(const Sandbox& sb, const Instruction& line) {
  if (sb_->get_result(0)->code == ErrorCode::NORMAL) {
    return true;
  }

  if(!is_supported_deref(line))
    return false;

  CpuState cs = *(sb_->get_result(0));
  const auto addr = get_addr(cs, line);
  const auto size = get_size(line);

  // If the address is already allocated, there's a segfault,
  // it's misaligned and we allow misaligned, then we're ok.
  if(allow_unaligned_ && is_misaligned(addr, size) &&
      cs.code == ErrorCode::SIGSEGV_ &&
      (already_allocated(cs.stack, addr, size) ||
       already_allocated(cs.heap, addr, size))) {
    return true;
  }

  return false;
}

bool StateGen::is_supported_deref(const Instruction& instr) {
  // Special support for push/pop/ret
  if (instr.is_push() || instr.is_pop() || instr.is_any_return() || instr.is_call()) {
    return true;
  }

  // No support for implicit memory accesses
  if (instr.is_implicit_memory_dereference()) {
    error_message_ = "Implicit memory dereferences not supported.";
    return false;
  }

  if (instr.mem_index() == -1) {
    error_message_ = "Could not find an explicit or implicit memory dereference."
                     "  Bug somewhere (forgot retq?).";
    return false;
  }

  const auto mi = instr.mem_index();
  const auto op = instr.get_operand<M8>(mi);

  // No support for rip-offset form or segment register addressing
  if (op.rip_offset() || op.contains_seg()) {
    error_message_ = "No support for RIP offset or segment addressing";
    return false;
  }

  return true;
}

uint64_t StateGen::get_addr(const CpuState& cs, const Instruction& instr) const {
  // Special handling for implicit dereferences
  if (instr.is_push() || instr.is_call()) {
    return cs.gp[rsp].get_fixed_quad(0) - 8;
  } else if (instr.is_pop()) {
    return cs.gp[rsp].get_fixed_quad(0);
  } else if (instr.is_any_return()) {
    return cs.gp[rsp].get_fixed_quad(0);
  }

  const auto mi = instr.mem_index();
  const auto op = instr.get_operand<M8>(mi);

  uint64_t addr = 0;
  if (op.contains_base()) {
    if (op.addr_or()) {
      addr += cs.gp[op.get_base()].get_fixed_double(0);
    } else {
      addr += cs.gp[op.get_base()].get_fixed_quad(0);
    }
  }
  if (op.contains_index()) {
    auto scale = 1;
    switch (op.get_scale()) {
    case Scale::TIMES_2:
      scale = 2;
      break;
    case Scale::TIMES_4:
      scale = 4;
      break;
    case Scale::TIMES_8:
      scale = 8;
      break;
    default:
      scale = 1;
      break;
    }

    if (op.addr_or()) {
      addr += (scale * cs.gp[op.get_index()].get_fixed_double(0));
    } else {
      addr += (scale * cs.gp[op.get_index()].get_fixed_quad(0));
    }
  }

  /* We need to sign-extend the displacement from 32 to 64 bits */
  uint64_t displacement = (op.get_disp());
  if (displacement & 0x80000000) {
    displacement |= 0xffffffff00000000;
  }
  addr += displacement;

  return addr;
}

size_t StateGen::get_size(const Instruction& instr) const {
  // Special handling for implicit dereferences
  if (instr.is_push() || instr.is_pop() || instr.is_any_return() || instr.is_call()) {
    return 8;
  }

  // Otherwise, we can infer width from type
  const auto mi = instr.mem_index();
  return instr.get_operand<M8>(mi).size()/8;
}

bool StateGen::resize_within(Memory& mem, uint64_t addr, size_t size) const {
  // This should always be true, otherwise there'd be no work to do
  // * See the previous check against already_allocated() one level up
  assert((addr + size) > mem.upper_bound());

  const auto delta = addr + size - mem.upper_bound();
  if (mem.size() + delta > max_memory_) {
    return false;
  }

  mem.resize(mem.lower_bound(), mem.size() + delta);
  randomize_mem(mem);
  return true;
}

bool StateGen::resize_below(Memory& mem, uint64_t addr, size_t size) const {
  size_t new_size = 0;
  if (addr + size > mem.upper_bound()) {
    new_size = size;
  } else {
    new_size = mem.upper_bound() - addr;
  }

  if (new_size > max_memory_) {
    return false;
  }

  mem.resize(addr, new_size);
  randomize_mem(mem);
  return true;
}

bool StateGen::resize_above(Memory& mem, uint64_t addr, size_t size) const {
  const auto delta = addr + size - mem.upper_bound();
  if (mem.size() + delta > max_memory_) {
    return false;
  }

  mem.resize(mem.lower_bound(), mem.size() + delta);
  randomize_mem(mem);
  return true;
}

void StateGen::randomize_mem(Memory& mem) const {
  for (auto i = mem.lower_bound(), ie = mem.upper_bound(); i < ie; ++i) {
    if (!mem.is_valid(i)) {
      mem.set_valid(i, true);
      mem[i] = rand() % 256;
    }
  }
}

bool StateGen::resize_mem(Memory& mem, uint64_t addr, size_t size) const {
  if (mem.size() == 0) {
    mem.resize(addr, size);
    randomize_mem(mem);
    return true;
  } else if (mem.in_range(addr) && resize_within(mem, addr, size)) {
    return true;
  } else if (addr < mem.lower_bound() && resize_below(mem, addr, size)) {
    return true;
  } else if (addr >= mem.upper_bound() && resize_above(mem, addr, size)) {
    return true;
  } else {
    return false;
  }
}

bool StateGen::fix_misalignment(const CpuState& cs, CpuState& fixed, const Instruction& instr) {
  const auto mi = instr.mem_index();
  const auto op = instr.get_operand<M8>(mi);

  const auto addr = get_addr(cs, instr);
  const auto mask = 0x1f;
  const auto offset = addr & mask;

  if (op.contains_base()) {
    const auto current = cs.gp[op.get_base()].get_fixed_quad(0);
    if(((current - offset) & mask) && !tried_to_fix_misalign_) {
      const auto new_byte = (current & mask) - offset;
      fixed.gp[op.get_base()].get_fixed_byte(0) = new_byte;
      tried_to_fix_misalign_ = true;
      return true;
    } else {
      error_message_ = "Could not fix misaligned memory reference.";
      tried_to_fix_misalign_ = false;
      return false;
    }
  } else {
    error_message_ = "Could not find misaligned memory reference.";
    tried_to_fix_misalign_ = false;
    return false;
  }

}

bool StateGen::fix(const CpuState& cs, CpuState& fixed, const Instruction& instr) {
  // Clear the error message unless something bad happens.
  error_message_ = "";

  // Only sigsegv is fixable
  if (cs.code != ErrorCode::SIGSEGV_) {
    error_message_ = "Interrupt was not segfault, but signal " + std::to_string((int)cs.code) + " instead.";
    return false;
  }
  // Only explicit dereferences are fixable
  if (!is_supported_deref(instr)) {
    return false;
  }

  const auto addr = get_addr(cs, instr);
  const auto size = get_size(instr);

  // We can't do anything about misaligned memory or pre-allocated memory
  if (is_misaligned(addr, size) && !allow_unaligned_) {
    return fix_misalignment(cs, fixed, instr);
  } else if (already_allocated(fixed.stack, addr, size)) {
    tried_to_fix_misalign_ = false;
    error_message_ = "Memory was already allocated in stack.";
    return false;
  } else if (already_allocated(fixed.heap, addr, size)) {
    tried_to_fix_misalign_ = false;
    error_message_ = "Memory was already allocated in heap.";
    return false;
  }

  // If we can't resize stack or heap, give up.
  if (!resize_mem(fixed.stack, addr, size) && !resize_mem(fixed.heap, addr, size)) {
    error_message_ = "Could not resize memory.";
    return false;
  }

  // If stack and heap overlap now, give up. This memory is broken.
  if (!(fixed.heap.upper_bound() < fixed.stack.lower_bound() ||
        fixed.stack.upper_bound() < fixed.heap.lower_bound())) {
    error_message_ = "Heap and stack overlap.";
    return false;
  }

  // Look like we did something right. Return success.
  return true;
}

} // namespace stoke
<|endoftext|>