diff options
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 110 |
1 files changed, 85 insertions, 25 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 4aefcba..9b9ca12 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -144,6 +144,15 @@ bool OpenGLRenderer::isDeferred() { } void OpenGLRenderer::setViewport(int width, int height) { + initViewport(width, height); + + glDisable(GL_DITHER); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + glEnableVertexAttribArray(Program::kBindingPosition); +} + +void OpenGLRenderer::initViewport(int width, int height) { mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); mWidth = width; @@ -151,11 +160,6 @@ void OpenGLRenderer::setViewport(int width, int height) { mFirstSnapshot->height = height; mFirstSnapshot->viewport.set(0, 0, width, height); - - glDisable(GL_DITHER); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - glEnableVertexAttribArray(Program::kBindingPosition); } int OpenGLRenderer::prepare(bool opaque) { @@ -171,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 @@ -184,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); @@ -206,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) { @@ -251,8 +281,9 @@ void OpenGLRenderer::interrupt() { void OpenGLRenderer::resume() { sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot; - glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight()); + glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); mCaches.scissorEnabled = glIsEnabled(GL_SCISSOR_TEST); @@ -261,7 +292,6 @@ void OpenGLRenderer::resume() { dirtyClip(); mCaches.activeTexture(0); - glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); mCaches.blend = true; glEnable(GL_BLEND); @@ -269,6 +299,15 @@ void OpenGLRenderer::resume() { glBlendEquation(GL_FUNC_ADD); } +void OpenGLRenderer::resumeAfterLayer() { + sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot; + glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight()); + glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); + + mCaches.resetScissor(); + dirtyClip(); +} + void OpenGLRenderer::detachFunctor(Functor* functor) { mFunctors.remove(functor); } @@ -624,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(); @@ -637,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(); @@ -677,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; @@ -1081,6 +1113,22 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl return !clipRect.intersects(r); } +bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom, + Rect& transformed, Rect& clip) { + if (mSnapshot->isIgnored()) { + return true; + } + + transformed.set(left, top, right, bottom); + mSnapshot->transform->mapRect(transformed); + transformed.snapToPixelBoundaries(); + + clip.set(*mSnapshot->clipRect); + clip.snapToPixelBoundaries(); + + return !clip.intersects(transformed); +} + bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { if (mSnapshot->isIgnored()) { return true; @@ -2574,22 +2622,33 @@ status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { } status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { - if (!layer || quickReject(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight())) { + if (!layer) { return DrawGlInfo::kStatusDone; } - bool debugLayerUpdate = false; + Rect transformed; + Rect clip; + const bool rejected = quickRejectNoScissor(x, y, + x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip); + + if (rejected) { + return DrawGlInfo::kStatusDone; + } + bool debugLayerUpdate = false; if (layer->deferredUpdateScheduled && layer->renderer && layer->displayList) { OpenGLRenderer* renderer = layer->renderer; Rect& dirty = layer->dirtyRect; - interrupt(); + 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(); - resume(); + + resumeAfterLayer(); + startTiling(mSnapshot); dirty.setEmpty(); layer->deferredUpdateScheduled = false; @@ -2599,6 +2658,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain debugLayerUpdate = mCaches.debugLayersUpdates; } + mCaches.setScissorEnabled(!clip.contains(transformed)); mCaches.activeTexture(0); if (CC_LIKELY(!layer->region.isEmpty())) { |
