Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7dfc05f authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Update snapshot upon saveLayer deferral" into jb-mr2-dev

parents 7e55414f d90144db
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public:
            renderer.restoreDisplayState(op->state, kStateDeferFlag_Draw);

#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
            renderer.eventMark(strlen(op->name()), op->name());
            renderer.eventMark(op->name());
#endif
            status |= op->applyDraw(renderer, dirty, 0);
            logBuffer.writeCommand(0, op->name());
@@ -134,7 +134,6 @@ public:
    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty) {
        DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount);
        renderer.restoreToCount(mRestoreCount);

        return DrawGlInfo::kStatusDone;
    }

@@ -373,9 +372,10 @@ status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) {
    DEFER_LOGD("--flushing");
    renderer.eventMark("Flush");

    DrawModifiers restoreDrawModifiers = renderer.getDrawModifiers();
    renderer.restoreToCount(1);
    status |= replayBatchList(mBatches, renderer, dirty);
    renderer.resetDrawModifiers();
    renderer.setDrawModifiers(restoreDrawModifiers);

    DEFER_LOGD("--flush complete, returning %x", status);

+5 −4
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public:
    void addDrawOp(OpenGLRenderer& renderer, DrawOp* op);

private:
    /*
    /**
     * Resets the batching back-pointers, creating a barrier in the operation stream so that no ops
     * added in the future will be inserted into a batch that already exist.
     */
@@ -88,9 +88,10 @@ private:
    int getStateOpDeferFlags() const;
    int getDrawOpDeferFlags() const;

    /*
     *
     * at defer time, stores the savecount of save/saveLayer ops that were 
    /**
     * At defer time, stores the *defer time* savecount of save/saveLayer ops that were deferred, so
     * that when an associated restoreToCount is deferred, it can be recorded as a
     * RestoreToCountBatch
     */
    Vector<int> mSaveStack;
    int mComplexClipStackStart;
+1 −1
Original line number Diff line number Diff line
@@ -443,7 +443,7 @@ public:
        : mReplayStruct(replayStruct), mLevel(level) {}
    inline void operator()(DisplayListOp* operation, int saveCount) {
#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
        replayStruct.mRenderer.eventMark(operation->name());
        mReplayStruct.mRenderer.eventMark(operation->name());
#endif
        operation->replay(mReplayStruct, saveCount, mLevel);
    }
+6 −1
Original line number Diff line number Diff line
@@ -284,8 +284,13 @@ public:

    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level) {
        // NOTE: don't bother with actual saveLayer, instead issuing it at flush time
        int newSaveCount = deferStruct.mRenderer.save(mFlags);
        int newSaveCount = deferStruct.mRenderer.getSaveCount();
        deferStruct.mDeferredList.addSaveLayer(deferStruct.mRenderer, this, newSaveCount);

        // NOTE: don't issue full saveLayer, since that has side effects/is costly. instead just
        // setup the snapshot for deferral, and re-issue the op at flush time
        deferStruct.mRenderer.saveLayerDeferred(mArea.left, mArea.top, mArea.right, mArea.bottom,
                mAlpha, mMode, mFlags);
    }

    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+64 −39
Original line number Diff line number Diff line
@@ -112,7 +112,10 @@ static const Blender gBlendsSwap[] = {

OpenGLRenderer::OpenGLRenderer():
        mCaches(Caches::getInstance()), mExtensions(Extensions::getInstance()) {
    resetDrawModifiers();
    mDrawModifiers.mShader = NULL;
    mDrawModifiers.mColorFilter = NULL;
    mDrawModifiers.mHasShadow = false;
    mDrawModifiers.mHasDrawFilter = false;

    memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices));

@@ -643,6 +646,63 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
    return count;
}

void OpenGLRenderer::calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer) {
    const Rect untransformedBounds(bounds);

    currentTransform().mapRect(bounds);

    // Layers only make sense if they are in the framebuffer's bounds
    if (bounds.intersect(*mSnapshot->clipRect)) {
        // We cannot work with sub-pixels in this case
        bounds.snapToPixelBoundaries();

        // When the layer is not an FBO, we may use glCopyTexImage so we
        // need to make sure the layer does not extend outside the bounds
        // of the framebuffer
        if (!bounds.intersect(mSnapshot->previous->viewport)) {
            bounds.setEmpty();
        } else if (fboLayer) {
            clip.set(bounds);
            mat4 inverse;
            inverse.loadInverse(currentTransform());
            inverse.mapRect(clip);
            clip.snapToPixelBoundaries();
            if (clip.intersect(untransformedBounds)) {
                clip.translate(-untransformedBounds.left, -untransformedBounds.top);
                bounds.set(untransformedBounds);
            } else {
                clip.setEmpty();
            }
        }
    } else {
        bounds.setEmpty();
    }
}

int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom,
        int alpha, SkXfermode::Mode mode, int flags) {
    const GLuint previousFbo = mSnapshot->fbo;
    const int count = saveSnapshot(flags);

    if (!mSnapshot->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
        // initialize the snapshot as though it almost represents an FBO layer so deferred draw
        // operations will be able to store and restore the current clip and transform info, and
        // quick rejection will be correct (for display lists)

        Rect bounds(left, top, right, bottom);
        Rect clip;
        calculateLayerBoundsAndClip(bounds, clip, true);

        if (!bounds.isEmpty() && !clip.isEmpty()) {
            mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
            mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
        }
    }

    return count;
}


/**
 * Layers are viewed by Skia are slightly different than layers in image editing
 * programs (for instance.) When a layer is created, previously created layers
@@ -704,35 +764,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto
    // Window coordinates of the layer
    Rect clip;
    Rect bounds(left, top, right, bottom);
    Rect untransformedBounds(bounds);
    currentTransform().mapRect(bounds);

    // Layers only make sense if they are in the framebuffer's bounds
    if (bounds.intersect(*mSnapshot->clipRect)) {
        // We cannot work with sub-pixels in this case
        bounds.snapToPixelBoundaries();

        // When the layer is not an FBO, we may use glCopyTexImage so we
        // need to make sure the layer does not extend outside the bounds
        // of the framebuffer
        if (!bounds.intersect(mSnapshot->previous->viewport)) {
            bounds.setEmpty();
        } else if (fboLayer) {
            clip.set(bounds);
            mat4 inverse;
            inverse.loadInverse(currentTransform());
            inverse.mapRect(clip);
            clip.snapToPixelBoundaries();
            if (clip.intersect(untransformedBounds)) {
                clip.translate(-left, -top);
                bounds.set(untransformedBounds);
            } else {
                clip.setEmpty();
            }
        }
    } else {
        bounds.setEmpty();
    }
    calculateLayerBoundsAndClip(bounds, clip, fboLayer);

    if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize ||
            bounds.getHeight() > mCaches.maxTextureSize ||
@@ -1201,13 +1233,6 @@ void OpenGLRenderer::clearLayerRegions() {
// State Deferral
///////////////////////////////////////////////////////////////////////////////

void OpenGLRenderer::resetDrawModifiers() {
    mDrawModifiers.mShader = NULL;
    mDrawModifiers.mColorFilter = NULL;
    mDrawModifiers.mHasShadow = false;
    mDrawModifiers.mHasDrawFilter = false;
}

bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) {
    const Rect& currentClip = *(mSnapshot->clipRect);
    const mat4& currentMatrix = *(mSnapshot->transform);
@@ -1246,7 +1271,7 @@ void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, int
        mSnapshot->alpha = state.mAlpha;
    }

    if (!state.mClip.isEmpty()) { //stateDeferFlags & kStateDeferFlag_Clip) {
    if (!state.mClip.isEmpty()) {
        mSnapshot->setClip(state.mClip.left, state.mClip.top, state.mClip.right, state.mClip.bottom);
        dirtyClip();
    }
@@ -1805,7 +1830,7 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty,
    // All the usual checks and setup operations (quickReject, setupDraw, etc.)
    // will be performed by the display list itself
    if (displayList && displayList->isRenderable()) {
        if (true || CC_UNLIKELY(mCaches.drawDeferDisabled)) { // NOTE: temporary workaround
        if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
            ReplayStateStruct replayStruct(*this, dirty, replayFlags);
            displayList->replay(replayStruct, 0);
            return replayStruct.mDrawGlStatus;
Loading