diff options
author | Romain Guy <romainguy@google.com> | 2013-03-01 14:31:04 -0800 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2013-03-01 16:04:53 -0800 |
commit | 0f6675332c04c74909425d1d328f02b32c0ff40e (patch) | |
tree | 53a912c204ba470a0d6cd2c5701a1aef614cc7eb /libs/hwui | |
parent | 8b5aa4846939975adacd6ea1d2a57a2493ac0216 (diff) | |
download | frameworks_base-0f6675332c04c74909425d1d328f02b32c0ff40e.zip frameworks_base-0f6675332c04c74909425d1d328f02b32c0ff40e.tar.gz frameworks_base-0f6675332c04c74909425d1d328f02b32c0ff40e.tar.bz2 |
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
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/Caches.cpp | 28 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 3 | ||||
-rw-r--r-- | libs/hwui/DeferredDisplayList.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/DisplayListOp.h | 25 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 24 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 17 | ||||
-rw-r--r-- | 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 5befb95..a1cc2e8 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -50,9 +50,9 @@ namespace uirenderer { Caches::Caches(): Singleton<Caches>(), 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 c35ad88..ca699d5 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 8962964..a4e9950 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 9ecfb5a..4a72477 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 16218fa..b011443 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 bff3b97..38619bf 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 7e9734f..ff6f332 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 cfad593..1bfd3c0 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. @@ -291,6 +293,11 @@ public: } /** + * 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 * this method must always be followed later on by a call to endMark(). @@ -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 d48b612..e804644 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 { |