Loading core/java/android/view/HardwareRenderer.java +6 −3 Original line number Diff line number Diff line Loading @@ -1136,9 +1136,8 @@ public abstract class HardwareRenderer { } } int status = onPreDraw(dirty); int saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); int saveCount = 0; int status = DisplayList.STATUS_DONE; try { view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) Loading @@ -1164,6 +1163,10 @@ public abstract class HardwareRenderer { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } status = onPreDraw(dirty); saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); if (mProfileEnabled) { long now = System.nanoTime(); float total = (now - getDisplayListStartTime) * 0.000001f; Loading libs/hwui/Caches.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -429,13 +429,13 @@ void Caches::resetScissor() { void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) { if (extensions.hasTiledRendering()) { glStartTilingQCOM(x, y, width, height, GL_COLOR_BUFFER_BIT0_QCOM); } } void Caches::endTiling() { if (extensions.hasTiledRendering()) { glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM); } } Loading libs/hwui/OpenGLRenderer.cpp +36 −14 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto mSaveCount = 1; mSnapshot->setClip(left, top, right, bottom); mDirtyClip = opaque; mDirtyClip = mOpaqueFrame = opaque; // If we know that we are going to redraw the entire framebuffer, // perform a discard to let the driver know we don't need to preserve Loading @@ -188,6 +188,9 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto syncState(); mTilingSnapshot = mSnapshot; startTiling(); if (!opaque) { mCaches.enableScissor(); mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top); Loading @@ -210,7 +213,30 @@ void OpenGLRenderer::syncState() { } } void OpenGLRenderer::startTiling() { startTiling(mTilingSnapshot); } void OpenGLRenderer::startTiling(const sp<Snapshot>& s) { bool opaque = mOpaqueFrame; Rect* clip = mTilingSnapshot->clipRect; if (s->flags & Snapshot::kFlagIsFboLayer) { opaque = !s->layer->isBlend(); clip = s->clipRect; } mCaches.startTiling(clip->left, s->height - clip->bottom, clip->right - clip->left, clip->bottom - clip->top, opaque); } void OpenGLRenderer::endTiling() { mCaches.endTiling(); } void OpenGLRenderer::finish() { endTiling(); #if DEBUG_OPENGL GLenum status = GL_NO_ERROR; while ((status = glGetError()) != GL_NO_ERROR) { Loading Loading @@ -637,6 +663,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui mSnapshot->flags |= Snapshot::kFlagDirtyOrtho; mSnapshot->orthoMatrix.load(mOrthoMatrix); endTiling(); // Bind texture to FBO glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo()); layer->bindTexture(); Loading @@ -650,18 +677,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layer->getTexture(), 0); #if DEBUG_LAYERS_AS_REGIONS GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { ALOGE("Framebuffer incomplete (GL error code 0x%x)", status); glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); Caches::getInstance().resourceCache.decrementRefcount(layer); return false; } #endif startTiling(mSnapshot); // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering mCaches.enableScissor(); Loading Loading @@ -690,11 +706,14 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer; if (fboLayer) { endTiling(); // Detach the texture from the FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); // Unbind current FBO and restore previous one glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo); startTiling(previous); } Layer* layer = current->layer; Loading Loading @@ -2621,12 +2640,15 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain OpenGLRenderer* renderer = layer->renderer; Rect& dirty = layer->dirtyRect; endTiling(); renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight()); renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, !layer->isBlend()); renderer->drawDisplayList(layer->displayList, dirty, DisplayList::kReplayFlag_ClipChildren); renderer->finish(); resumeAfterLayer(); startTiling(mSnapshot); dirty.setEmpty(); layer->deferredUpdateScheduled = false; Loading libs/hwui/OpenGLRenderer.h +18 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,20 @@ private: */ void syncState(); /** * Tells the GPU what part of the screen is about to be redrawn. * This method needs to be invoked every time getTargetFbo() is * bound again. */ void startTiling(); void startTiling(const sp<Snapshot>& snapshot); /** * Tells the GPU that we are done drawing the frame or that we * are switching to another render target. */ void endTiling(); /** * Saves the current state of the renderer as a new snapshot. * The new snapshot is saved in mSnapshot and the previous snapshot Loading Loading @@ -735,6 +749,8 @@ private: sp<Snapshot> mFirstSnapshot; // Current state sp<Snapshot> mSnapshot; // State used to define the clipping region sp<Snapshot> mTilingSnapshot; // Shaders SkiaShader* mShader; Loading Loading @@ -784,6 +800,8 @@ private: GLuint mTextureUnit; // Track dirty regions, true by default bool mTrackDirtyRegions; // Indicate whether we are drawing an opaque frame bool mOpaqueFrame; friend class DisplayListRenderer; Loading tests/HwAccelerationTest/res/layout/text_fade.xml +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ android:ellipsize="marquee" android:fadingEdgeLength="16sp" android:fadingEdge="horizontal" android:requiresFadingEdge="horizontal" android:text="This is a really really really really really really long string" android:textSize="16sp" /> Loading Loading
core/java/android/view/HardwareRenderer.java +6 −3 Original line number Diff line number Diff line Loading @@ -1136,9 +1136,8 @@ public abstract class HardwareRenderer { } } int status = onPreDraw(dirty); int saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); int saveCount = 0; int status = DisplayList.STATUS_DONE; try { view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) Loading @@ -1164,6 +1163,10 @@ public abstract class HardwareRenderer { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } status = onPreDraw(dirty); saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); if (mProfileEnabled) { long now = System.nanoTime(); float total = (now - getDisplayListStartTime) * 0.000001f; Loading
libs/hwui/Caches.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -429,13 +429,13 @@ void Caches::resetScissor() { void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) { if (extensions.hasTiledRendering()) { glStartTilingQCOM(x, y, width, height, GL_COLOR_BUFFER_BIT0_QCOM); } } void Caches::endTiling() { if (extensions.hasTiledRendering()) { glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM); } } Loading
libs/hwui/OpenGLRenderer.cpp +36 −14 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto mSaveCount = 1; mSnapshot->setClip(left, top, right, bottom); mDirtyClip = opaque; mDirtyClip = mOpaqueFrame = opaque; // If we know that we are going to redraw the entire framebuffer, // perform a discard to let the driver know we don't need to preserve Loading @@ -188,6 +188,9 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto syncState(); mTilingSnapshot = mSnapshot; startTiling(); if (!opaque) { mCaches.enableScissor(); mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top); Loading @@ -210,7 +213,30 @@ void OpenGLRenderer::syncState() { } } void OpenGLRenderer::startTiling() { startTiling(mTilingSnapshot); } void OpenGLRenderer::startTiling(const sp<Snapshot>& s) { bool opaque = mOpaqueFrame; Rect* clip = mTilingSnapshot->clipRect; if (s->flags & Snapshot::kFlagIsFboLayer) { opaque = !s->layer->isBlend(); clip = s->clipRect; } mCaches.startTiling(clip->left, s->height - clip->bottom, clip->right - clip->left, clip->bottom - clip->top, opaque); } void OpenGLRenderer::endTiling() { mCaches.endTiling(); } void OpenGLRenderer::finish() { endTiling(); #if DEBUG_OPENGL GLenum status = GL_NO_ERROR; while ((status = glGetError()) != GL_NO_ERROR) { Loading Loading @@ -637,6 +663,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui mSnapshot->flags |= Snapshot::kFlagDirtyOrtho; mSnapshot->orthoMatrix.load(mOrthoMatrix); endTiling(); // Bind texture to FBO glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo()); layer->bindTexture(); Loading @@ -650,18 +677,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layer->getTexture(), 0); #if DEBUG_LAYERS_AS_REGIONS GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { ALOGE("Framebuffer incomplete (GL error code 0x%x)", status); glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); Caches::getInstance().resourceCache.decrementRefcount(layer); return false; } #endif startTiling(mSnapshot); // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering mCaches.enableScissor(); Loading Loading @@ -690,11 +706,14 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer; if (fboLayer) { endTiling(); // Detach the texture from the FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); // Unbind current FBO and restore previous one glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo); startTiling(previous); } Layer* layer = current->layer; Loading Loading @@ -2621,12 +2640,15 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain OpenGLRenderer* renderer = layer->renderer; Rect& dirty = layer->dirtyRect; endTiling(); renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight()); renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, !layer->isBlend()); renderer->drawDisplayList(layer->displayList, dirty, DisplayList::kReplayFlag_ClipChildren); renderer->finish(); resumeAfterLayer(); startTiling(mSnapshot); dirty.setEmpty(); layer->deferredUpdateScheduled = false; Loading
libs/hwui/OpenGLRenderer.h +18 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,20 @@ private: */ void syncState(); /** * Tells the GPU what part of the screen is about to be redrawn. * This method needs to be invoked every time getTargetFbo() is * bound again. */ void startTiling(); void startTiling(const sp<Snapshot>& snapshot); /** * Tells the GPU that we are done drawing the frame or that we * are switching to another render target. */ void endTiling(); /** * Saves the current state of the renderer as a new snapshot. * The new snapshot is saved in mSnapshot and the previous snapshot Loading Loading @@ -735,6 +749,8 @@ private: sp<Snapshot> mFirstSnapshot; // Current state sp<Snapshot> mSnapshot; // State used to define the clipping region sp<Snapshot> mTilingSnapshot; // Shaders SkiaShader* mShader; Loading Loading @@ -784,6 +800,8 @@ private: GLuint mTextureUnit; // Track dirty regions, true by default bool mTrackDirtyRegions; // Indicate whether we are drawing an opaque frame bool mOpaqueFrame; friend class DisplayListRenderer; Loading
tests/HwAccelerationTest/res/layout/text_fade.xml +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ android:ellipsize="marquee" android:fadingEdgeLength="16sp" android:fadingEdge="horizontal" android:requiresFadingEdge="horizontal" android:text="This is a really really really really really really long string" android:textSize="16sp" /> Loading