Loading libs/hwui/DeferredDisplayList.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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; } Loading Loading @@ -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); Loading libs/hwui/DeferredDisplayList.h +5 −4 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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; Loading libs/hwui/DisplayList.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); } Loading libs/hwui/DisplayListOp.h +6 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading libs/hwui/OpenGLRenderer.cpp +64 −39 Original line number Diff line number Diff line Loading @@ -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)); Loading Loading @@ -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 Loading Loading @@ -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 || Loading Loading @@ -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); Loading Loading @@ -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(); } Loading Loading @@ -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 Loading
libs/hwui/DeferredDisplayList.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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; } Loading Loading @@ -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); Loading
libs/hwui/DeferredDisplayList.h +5 −4 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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; Loading
libs/hwui/DisplayList.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); } Loading
libs/hwui/DisplayListOp.h +6 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading
libs/hwui/OpenGLRenderer.cpp +64 −39 Original line number Diff line number Diff line Loading @@ -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)); Loading Loading @@ -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 Loading Loading @@ -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 || Loading Loading @@ -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); Loading Loading @@ -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(); } Loading Loading @@ -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