diff options
author | Romain Guy <romainguy@google.com> | 2012-09-19 17:25:38 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2012-09-19 21:10:09 -0700 |
commit | 2b7028eabac80cec170572bc0e945a1d4224e595 (patch) | |
tree | 116f24c751ece653a5c1e08aa9c142ad1e142b25 /libs | |
parent | 4be07ade3658da9345067780520ddbd266900ee4 (diff) | |
download | frameworks_base-2b7028eabac80cec170572bc0e945a1d4224e595.zip frameworks_base-2b7028eabac80cec170572bc0e945a1d4224e595.tar.gz frameworks_base-2b7028eabac80cec170572bc0e945a1d4224e595.tar.bz2 |
Add support for QCOM_tiled_rendering
Bug #7186819
This optional OpenGL extension can be used by tiled renderers to optimize
copies from main memory to tiles memory.
Change-Id: Id4a5d64e61ad17f50e773e8104b9bf584bb65077
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/Caches.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 50 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 18 |
3 files changed, 56 insertions, 16 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index edb4c10..b149bb9 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -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); } } diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 11eb7a1..9b9ca12 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -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 @@ -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); @@ -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) { @@ -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(); @@ -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(); @@ -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; @@ -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; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 8dcd33f..10ba86e 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -347,6 +347,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 * is linked from mSnapshot->previous. @@ -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; @@ -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; |