diff options
Diffstat (limited to 'libs/hwui')
| -rw-r--r-- | libs/hwui/DeferredDisplayList.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/DeferredDisplayList.h | 1 | ||||
| -rw-r--r-- | libs/hwui/FrameInfo.h | 5 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 21 | ||||
| -rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 26 | ||||
| -rw-r--r-- | libs/hwui/RenderNode.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/RenderProperties.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/renderstate/Stencil.cpp | 13 | ||||
| -rw-r--r-- | libs/hwui/renderstate/Stencil.h | 5 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 29 |
10 files changed, 52 insertions, 68 deletions
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index c78971a..dd6af03 100644 --- a/libs/hwui/DeferredDisplayList.cpp +++ b/libs/hwui/DeferredDisplayList.cpp @@ -638,8 +638,7 @@ void DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { DEFER_LOGD("--flushing"); renderer.eventMark("Flush"); - // save and restore (with draw modifiers) so that reordering doesn't affect final state - DrawModifiers restoreDrawModifiers = renderer.getDrawModifiers(); + // save and restore so that reordering doesn't affect final state renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); if (CC_LIKELY(mAvoidOverdraw)) { @@ -654,7 +653,6 @@ void DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { replayBatchList(mBatches, renderer, dirty); renderer.restoreToCount(1); - renderer.setDrawModifiers(restoreDrawModifiers); DEFER_LOGD("--flush complete, returning %x", status); clear(); diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h index f535afb..3d0ca6d 100644 --- a/libs/hwui/DeferredDisplayList.h +++ b/libs/hwui/DeferredDisplayList.h @@ -61,7 +61,6 @@ public: int mClipSideFlags; // specifies which sides of the bounds are clipped, unclipped if cleared bool mClipped; mat4 mMatrix; - DrawModifiers mDrawModifiers; float mAlpha; const RoundRectClipState* mRoundRectClipState; }; diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h index 65daf03..c8189b8 100644 --- a/libs/hwui/FrameInfo.h +++ b/libs/hwui/FrameInfo.h @@ -53,6 +53,7 @@ enum class FrameInfoFlags { kWindowLayoutChanged = 1 << 0, kRTAnimation = 1 << 1, kSurfaceCanvas = 1 << 2, + kSkippedFrame = 1 << 3, }; MAKE_FLAGS_ENUM(FrameInfoFlags) @@ -101,6 +102,10 @@ public: set(FrameInfoIndex::kFrameCompleted) = systemTime(CLOCK_MONOTONIC); } + void addFlag(FrameInfoFlags flag) { + set(FrameInfoIndex::kFlags) |= static_cast<uint64_t>(flag); + } + int64_t operator[](FrameInfoIndex index) const { if (index == FrameInfoIndex::kNumIndexes) return 0; return mFrameInfo[static_cast<int>(index)]; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 30935d5..7fc31b8 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -76,9 +76,6 @@ OpenGLRenderer::OpenGLRenderer(RenderState& renderState) , mLightRadius(FLT_MIN) , mAmbientShadowAlpha(0) , mSpotShadowAlpha(0) { - // *set* draw modifiers to be 0 - memset(&mDrawModifiers, 0, sizeof(mDrawModifiers)); - mDrawModifiers.mOverrideLayerAlpha = 1.0f; } OpenGLRenderer::~OpenGLRenderer() { @@ -1188,10 +1185,9 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef state.mClip.set(currentClip); } - // Transform, drawModifiers, and alpha always deferred, since they are used by state operations + // Transform and alpha always deferred, since they are used by state operations // (Note: saveLayer/restore use colorFilter and alpha, so we just save restore everything) state.mMatrix.load(*currentMatrix); - state.mDrawModifiers = mDrawModifiers; state.mAlpha = currentSnapshot()->alpha; // always store/restore, since it's just a pointer @@ -1202,7 +1198,6 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) { setMatrix(state.mMatrix); writableSnapshot()->alpha = state.mAlpha; - mDrawModifiers = state.mDrawModifiers; writableSnapshot()->roundRectClipState = state.mRoundRectClipState; if (state.mClipValid && !skipClipRestore) { @@ -1262,7 +1257,7 @@ void OpenGLRenderer::attachStencilBufferToLayer(Layer* layer) { endTiling(); RenderBuffer* buffer = mCaches.renderBufferCache.get( - Stencil::getSmallestStencilFormat(), + Stencil::getLayerStencilFormat(), layer->getWidth(), layer->getHeight()); layer->setStencilRenderBuffer(buffer); @@ -2541,21 +2536,11 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const { getAlphaAndModeDirect(paint, alpha, mode); - if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) { - // if drawing a layer, ignore the paint's alpha - *alpha = mDrawModifiers.mOverrideLayerAlpha * 255; - } *alpha *= currentSnapshot()->alpha; } float OpenGLRenderer::getLayerAlpha(const Layer* layer) const { - float alpha; - if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) { - alpha = mDrawModifiers.mOverrideLayerAlpha; - } else { - alpha = layer->getAlpha() / 255.0f; - } - return alpha * currentSnapshot()->alpha; + return (layer->getAlpha() / 255.0f) * currentSnapshot()->alpha; } }; // namespace uirenderer diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 5f8960a..c34eb2c 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -68,17 +68,6 @@ class RenderNode; class TextDrawFunctor; class VertexBuffer; -struct DrawModifiers { - DrawModifiers() - : mOverrideLayerAlpha(0.0f) {} - - void reset() { - mOverrideLayerAlpha = 0.0f; - } - - float mOverrideLayerAlpha; -}; - enum StateDeferFlags { kStateDeferFlag_Draw = 0x1, kStateDeferFlag_Clip = 0x2 @@ -236,9 +225,6 @@ public: void setDrawFilter(SkDrawFilter* filter); - // If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer) - void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; } - /** * Store the current display state (most importantly, the current clip and transform), and * additionally map the state's bounds from local to window coordinates. @@ -249,9 +235,6 @@ public: void restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore = false); void setupMergedMultiDraw(const Rect* clipRect); - const DrawModifiers& getDrawModifiers() { return mDrawModifiers; } - void setDrawModifiers(const DrawModifiers& drawModifiers) { mDrawModifiers = drawModifiers; } - bool isCurrentTransformSimple() { return currentTransform()->isSimple(); } @@ -523,8 +506,7 @@ protected: /** * Gets the alpha and xfermode out of a paint object. If the paint is null - * alpha will be 255 and the xfermode will be SRC_OVER. Accounts for both - * snapshot alpha, and overrideLayerAlpha + * alpha will be 255 and the xfermode will be SRC_OVER. Accounts for snapshot alpha. * * @param paint The paint to extract values from * @param alpha Where to store the resulting alpha @@ -533,7 +515,7 @@ protected: inline void getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const; /** - * Gets the alpha from a layer, accounting for snapshot alpha and overrideLayerAlpha + * Gets the alpha from a layer, accounting for snapshot alpha * * @param layer The layer from which the alpha is extracted */ @@ -868,10 +850,6 @@ private: // Default UV mapper const UvMapper mUvMapper; - // shader, filters, and shadow - DrawModifiers mDrawModifiers; - SkPaint mFilteredPaint; - // List of rectangles to clear after saveLayer() is invoked std::vector<Rect> mLayers; // List of layers to update at the beginning of a frame diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index ac4c0d0..8f95e0d 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -389,12 +389,9 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) { if (properties().getAlpha() < 1) { if (isLayer) { clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer - - renderer.setOverrideLayerAlpha(properties().getAlpha()); - } else { - LOG_ALWAYS_FATAL_IF(properties().getHasOverlappingRendering()); - renderer.scaleAlpha(properties().getAlpha()); } + LOG_ALWAYS_FATAL_IF(!isLayer && properties().getHasOverlappingRendering()); + renderer.scaleAlpha(properties().getAlpha()); } if (clipFlags) { Rect clipRect; @@ -902,7 +899,6 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo); handler(new (alloc) RestoreToCountOp(restoreTo), PROPERTY_SAVECOUNT, properties().getClipToBounds()); - renderer.setOverrideLayerAlpha(1.0f); DISPLAY_LIST_LOGD("%*sDone (%p, %s)", level * 2, "", this, getName()); handler.endMark(); diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index 0ed3c47..7b75690 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -149,12 +149,10 @@ void RenderProperties::debugOutputProperties(const int level) const { if (mPrimitiveFields.mAlpha < 1) { if (isLayer) { clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer - - ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha); - } else { - LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mHasOverlappingRendering); - ALOGD("%*sScaleAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha); } + + LOG_ALWAYS_FATAL_IF(!isLayer && mPrimitiveFields.mHasOverlappingRendering); + ALOGD("%*sScaleAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha); } if (clipFlags) { Rect clipRect; diff --git a/libs/hwui/renderstate/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp index cedb233..92a057d 100644 --- a/libs/hwui/renderstate/Stencil.cpp +++ b/libs/hwui/renderstate/Stencil.cpp @@ -42,12 +42,17 @@ uint8_t Stencil::getStencilSize() { return STENCIL_BUFFER_SIZE; } -GLenum Stencil::getSmallestStencilFormat() { +/** + * This method will return either GL_STENCIL_INDEX4_OES if supported, + * GL_STENCIL_INDEX8 if not. + * + * Layers can't use a single bit stencil because multi-rect ClipArea needs a high enough + * stencil resolution to represent the summation of multiple intersecting rect geometries. + */ +GLenum Stencil::getLayerStencilFormat() { #if !DEBUG_STENCIL const Extensions& extensions = Caches::getInstance().extensions(); - if (extensions.has1BitStencil()) { - return GL_STENCIL_INDEX1_OES; - } else if (extensions.has4BitStencil()) { + if (extensions.has4BitStencil()) { return GL_STENCIL_INDEX4_OES; } #endif diff --git a/libs/hwui/renderstate/Stencil.h b/libs/hwui/renderstate/Stencil.h index e4f0f3f..3a8f8eb 100644 --- a/libs/hwui/renderstate/Stencil.h +++ b/libs/hwui/renderstate/Stencil.h @@ -42,10 +42,7 @@ public: */ ANDROID_API static uint8_t getStencilSize(); - /** - * Returns the smallest stencil format accepted by render buffers. - */ - static GLenum getSmallestStencilFormat(); + static GLenum getLayerStencilFormat(); /** * Clears the stencil buffer. diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 9237151..3de3086 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -27,12 +27,25 @@ #include "../OpenGLRenderer.h" #include <algorithm> +#include <cutils/properties.h> #include <private/hwui/DrawGlInfo.h> #include <strings.h> #define TRIM_MEMORY_COMPLETE 80 #define TRIM_MEMORY_UI_HIDDEN 20 +#define PROPERTY_SKIP_EMPTY_DAMAGE "debug.hwui.skip_empty_damage" + +static bool sInitialized = false; +static bool sSkipEmptyDamage = true; + +static void initGlobals() { + if (sInitialized) return; + sInitialized = true; + sSkipEmptyDamage = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE, + sSkipEmptyDamage); +} + namespace android { namespace uirenderer { namespace renderthread { @@ -45,6 +58,9 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord())) , mRootRenderNode(rootRenderNode) , mJankTracker(thread.timeLord().frameIntervalNanos()) { + // Done lazily at first draw instead of at library load to avoid + // running pre-zygote fork + initGlobals(); mRenderThread.renderState().registerCanvasContext(this); mProfiler.setDensity(mRenderThread.mainDisplayInfo().density); } @@ -203,12 +219,17 @@ void CanvasContext::draw() { LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, "drawRenderNode called on a context with no canvas or surface!"); - profiler().markPlaybackStart(); - mCurrentFrameInfo->markIssueDrawCommandsStart(); - SkRect dirty; mDamageAccumulator.finish(&dirty); + if (dirty.isEmpty() && sSkipEmptyDamage) { + mCurrentFrameInfo->addFlag(FrameInfoFlags::kSkippedFrame); + return; + } + + profiler().markPlaybackStart(); + mCurrentFrameInfo->markIssueDrawCommandsStart(); + EGLint width, height; mEglManager.beginFrame(mEglSurface, &width, &height); if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { @@ -277,6 +298,8 @@ void CanvasContext::doFrame() { prepareTree(info, frameInfo); if (info.out.canDrawThisFrame) { draw(); + } else { + mCurrentFrameInfo->addFlag(FrameInfoFlags::kSkippedFrame); } } |
