From 0f6675332c04c74909425d1d328f02b32c0ff40e Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 1 Mar 2013 14:31:04 -0800 Subject: [PATCH] Precache glyphs at final raster size The deferred display lists model now allows us to precache glyphs at their exact size on screen. This change also removes debug markers when the renderer defers and reorders display lists. It also adds a flush event marker. Change-Id: I66ec5216dc12b93ecfdad52a7146b1cfb31fbeb4 --- libs/hwui/Caches.cpp | 28 ++++++++++++++++++++++++---- libs/hwui/Caches.h | 3 +++ libs/hwui/DeferredDisplayList.cpp | 3 +++ libs/hwui/DisplayListOp.h | 25 ++++++++++++++++++++++++- libs/hwui/DisplayListRenderer.cpp | 26 +++++--------------------- libs/hwui/DisplayListRenderer.h | 2 +- libs/hwui/OpenGLRenderer.cpp | 24 ++++++------------------ libs/hwui/OpenGLRenderer.h | 17 +++++++++-------- libs/hwui/font/Font.cpp | 3 ++- 9 files changed, 77 insertions(+), 54 deletions(-) diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 5befb9518dd19..a1cc2e8df653c 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -50,9 +50,9 @@ namespace uirenderer { Caches::Caches(): Singleton(), mExtensions(Extensions::getInstance()), mInitialized(false) { init(); initFont(); - initExtensions(); initConstraints(); initProperties(); + initExtensions(); mDebugLevel = readDebugLevel(); ALOGD("Enabling debug mode %d", mDebugLevel); @@ -103,15 +103,21 @@ void Caches::initFont() { void Caches::initExtensions() { if (mExtensions.hasDebugMarker()) { eventMark = glInsertEventMarkerEXT; - startMark = glPushGroupMarkerEXT; - endMark = glPopGroupMarkerEXT; + if ((drawDeferDisabled || drawReorderDisabled)) { + startMark = glPushGroupMarkerEXT; + endMark = glPopGroupMarkerEXT; + } else { + startMark = startMarkNull; + endMark = endMarkNull; + } + } else { eventMark = eventMarkNull; startMark = startMarkNull; endMark = endMarkNull; } - if (mExtensions.hasDebugLabel()) { + if (mExtensions.hasDebugLabel() && (drawDeferDisabled || drawReorderDisabled)) { setLabel = glLabelObjectEXT; getLabel = glGetObjectLabelEXT; } else { @@ -164,6 +170,20 @@ bool Caches::initProperties() { debugStencilClip = kStencilHide; } + if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) { + drawDeferDisabled = !strcasecmp(property, "true"); + INIT_LOGD(" Draw defer %s", drawDeferDisabled ? "disabled" : "enabled"); + } else { + INIT_LOGD(" Draw defer enabled"); + } + + if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) { + drawReorderDisabled = !strcasecmp(property, "true"); + INIT_LOGD(" Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled"); + } else { + INIT_LOGD(" Draw reorder enabled"); + } + return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw) || (prevDebugStencilClip != debugStencilClip); diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index c35ad8838f2b9..ca699d5668814 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -240,6 +240,9 @@ public: Program* currentProgram; bool scissorEnabled; + bool drawDeferDisabled; + bool drawReorderDisabled; + // VBO to draw with GLuint meshBuffer; diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index 8962964c541b7..a4e99504c125e 100644 --- a/libs/hwui/DeferredDisplayList.cpp +++ b/libs/hwui/DeferredDisplayList.cpp @@ -146,6 +146,8 @@ status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty, int32 if (isEmpty()) return status; // nothing to flush DEFER_LOGD("--flushing"); + renderer.eventMark("Flush"); + DrawModifiers restoreDrawModifiers = renderer.getDrawModifiers(); int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); int opCount = 0; @@ -166,6 +168,7 @@ status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty, int32 } DEFER_LOGD("--flushed, drew %d batches (total %d ops)", mBatches.size(), opCount); + renderer.restoreToCount(restoreTo); renderer.setDrawModifiers(restoreDrawModifiers); clear(); diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 9ecfb5a11f13a..4a724772e4138 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -147,7 +147,8 @@ public: if (!renderer.storeDisplayState(state)) { // op wasn't quick-rejected, so defer - deferredList->add(this, renderer.disallowReorder()); + deferredList->add(this, renderer.getCaches().drawReorderDisabled); + onDrawOpDeferred(renderer); } return DrawGlInfo::kStatusDone; @@ -156,6 +157,9 @@ public: virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, bool caching, int multipliedAlpha) = 0; + virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { + } + // returns true if bounds exist virtual bool getLocalBounds(Rect& localBounds) { return false; } @@ -1081,6 +1085,12 @@ public: OP_LOG("Draw some text, %d bytes", mBytesCount); } + virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { + SkPaint* paint = getPaint(renderer); + FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); + fontRenderer.precache(paint, mText, mCount, mat4::identity()); + } + virtual DeferredDisplayList::OpBatchId getBatchId() { return mPaint->getColor() == 0xff000000 ? DeferredDisplayList::kOpBatch_Text : @@ -1156,6 +1166,19 @@ public: mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom); } + /* + * When this method is invoked the state field is initialized to have the + * final rendering state. We can thus use it to process data as it will be + * used at draw time. + */ + virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { + SkPaint* paint = getPaint(renderer); + FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); + const bool pureTranslate = state.mMatrix.isPureTranslate(); + fontRenderer.precache(paint, mText, mCount, + pureTranslate ? mat4::identity() : state.mMatrix); + } + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, bool caching, int multipliedAlpha) { return renderer.drawText(mText, mBytesCount, mCount, mX, mY, diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 16218fa5f3c62..b011443b16ff4 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -403,11 +403,7 @@ status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, i DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, hOffset, vOffset, paint); - if (addDrawOp(op)) { - // precache if draw operation is visible - FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); - fontRenderer.precache(paint, text, count, mat4::identity()); - } + addDrawOp(op); return DrawGlInfo::kStatusDone; } @@ -420,11 +416,7 @@ status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int paint = refPaint(paint); DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); - if (addDrawOp(op)) { - // precache if draw operation is visible - FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); - fontRenderer.precache(paint, text, count, mat4::identity()); - } + addDrawOp(op); return DrawGlInfo::kStatusDone; } @@ -439,13 +431,7 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou paint = refPaint(paint); DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length); - if (addDrawOp(op)) { - // precache if draw operation is visible - FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); - const bool pureTranslate = mSnapshot->transform->isPureTranslate(); - fontRenderer.precache(paint, text, count, - pureTranslate ? mat4::identity() : *mSnapshot->transform); - } + addDrawOp(op); return DrawGlInfo::kStatusDone; } @@ -515,17 +501,15 @@ void DisplayListRenderer::addStateOp(StateOp* op) { addOpInternal(op); } -bool DisplayListRenderer::addDrawOp(DrawOp* op) { - bool rejected = false; +void DisplayListRenderer::addDrawOp(DrawOp* op) { Rect localBounds; if (op->getLocalBounds(localBounds)) { - rejected = quickRejectNoScissor(localBounds.left, localBounds.top, + bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top, localBounds.right, localBounds.bottom); op->setQuickRejected(rejected); } mHasDrawOps = true; addOpInternal(op); - return !rejected; } }; // namespace uirenderer diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index bff3b97efbdb0..38619bf96cff1 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -195,7 +195,7 @@ private: LinearAllocator& alloc() { return mDisplayListData->allocator; } void addStateOp(StateOp* op); - bool addDrawOp(DrawOp* op); // returns true if op not rejected + void addDrawOp(DrawOp* op); void addOpInternal(DisplayListOp* op) { insertRestoreToCount(); insertTranslate(); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7e9734f9e57de..ff6f332e6791b 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -122,8 +122,6 @@ OpenGLRenderer::OpenGLRenderer(): mFirstSnapshot = new Snapshot; mScissorOptimizationDisabled = false; - mDrawDeferDisabled = false; - mDrawReorderDisabled = false; } OpenGLRenderer::~OpenGLRenderer() { @@ -140,20 +138,6 @@ void OpenGLRenderer::initProperties() { } else { INIT_LOGD(" Scissor optimization enabled"); } - - if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) { - mDrawDeferDisabled = !strcasecmp(property, "true"); - INIT_LOGD(" Draw defer %s", mDrawDeferDisabled ? "disabled" : "enabled"); - } else { - INIT_LOGD(" Draw defer enabled"); - } - - if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) { - mDrawReorderDisabled = !strcasecmp(property, "true"); - INIT_LOGD(" Draw reorder %s", mDrawReorderDisabled ? "disabled" : "enabled"); - } else { - INIT_LOGD(" Draw reorder enabled"); - } } /////////////////////////////////////////////////////////////////////////////// @@ -462,6 +446,10 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { // Debug /////////////////////////////////////////////////////////////////////////////// +void OpenGLRenderer::eventMark(const char* name) const { + mCaches.eventMark(0, name); +} + void OpenGLRenderer::startMark(const char* name) const { mCaches.startMark(0, name); } @@ -1815,7 +1803,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 (CC_UNLIKELY(mDrawDeferDisabled)) { + if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { return displayList->replay(*this, dirty, flags, 0); } @@ -2710,7 +2698,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, setupDrawShaderUniforms(!isPerspective); setupDrawTextGammaUniforms(); - const Rect* clip = mSnapshot->hasPerspectiveTransform() ? NULL : mSnapshot->clipRect; + const Rect* clip = isPerspective ? NULL : mSnapshot->clipRect; Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); const bool hasActiveLayer = hasLayer(); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index cfad59389d7be..1bfd3c07d6d50 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -270,8 +270,6 @@ public: (mSnapshot->flags & Snapshot::kFlagFboTarget); // ensure we're not in a layer } - bool disallowReorder() { return mDrawReorderDisabled; } - bool storeDisplayState(DeferredDisplayState& state); void restoreDisplayState(const DeferredDisplayState& state); @@ -282,6 +280,10 @@ public: return mSnapshot->transform->isSimple(); } + Caches& getCaches() { + return mCaches; + } + /** * Sets the alpha on the current snapshot. This alpha value will be modulated * with other alpha values when drawing primitives. @@ -290,6 +292,11 @@ public: mSnapshot->alpha = alpha; } + /** + * Inserts a named event marker in the stream of GL commands. + */ + void eventMark(const char* name) const; + /** * Inserts a named group marker in the stream of GL commands. This marker * can be used by tools to group commands into logical groups. A call to @@ -439,10 +446,6 @@ protected: return false; } - Caches& getCaches() { - return mCaches; - } - private: /** * Discards the content of the framebuffer if supported by the driver. @@ -957,8 +960,6 @@ private: // See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in // Properties.h bool mScissorOptimizationDisabled; - bool mDrawDeferDisabled; - bool mDrawReorderDisabled; // No-ops start/endTiling when set bool mSuppressTiling; diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp index d48b6128cc2bf..e8046443b946a 100644 --- a/libs/hwui/font/Font.cpp +++ b/libs/hwui/font/Font.cpp @@ -284,7 +284,8 @@ CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool pre // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { - const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit, &mDescription.mLookupTransform); + const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit, + &mDescription.mLookupTransform); updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching); } } else {