diff options
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 114 |
1 files changed, 32 insertions, 82 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 31f399a..ede89d7 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -35,6 +35,7 @@ #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" #include "Fence.h" +#include "RenderState.h" #include "PathTessellator.h" #include "Properties.h" #include "ShadowTessellator.h" @@ -129,8 +130,10 @@ static inline T min(T a, T b) { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// -OpenGLRenderer::OpenGLRenderer(): - mCaches(Caches::getInstance()), mExtensions(Extensions::getInstance()) { +OpenGLRenderer::OpenGLRenderer(RenderState& renderState) + : mCaches(Caches::getInstance()) + , mExtensions(Extensions::getInstance()) + , mRenderState(renderState) { // *set* draw modifiers to be 0 memset(&mDrawModifiers, 0, sizeof(mDrawModifiers)); mDrawModifiers.mOverrideLayerAlpha = 1.0f; @@ -187,7 +190,7 @@ status_t OpenGLRenderer::startFrame() { discardFramebuffer(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom); - glViewport(0, 0, getWidth(), getHeight()); + mRenderState.setViewport(getWidth(), getHeight()); // Functors break the tiling extension in pretty spectacular ways // This ensures we don't use tiling when a functor is going to be @@ -311,46 +314,9 @@ void OpenGLRenderer::finish() { mFrameStarted = false; } -void OpenGLRenderer::interrupt() { - if (mCaches.currentProgram) { - if (mCaches.currentProgram->isInUse()) { - mCaches.currentProgram->remove(); - mCaches.currentProgram = NULL; - } - } - mCaches.resetActiveTexture(); - mCaches.unbindMeshBuffer(); - mCaches.unbindIndicesBuffer(); - mCaches.resetVertexPointers(); - mCaches.disableTexCoordsVertexArray(); - debugOverdraw(false, false); -} - -void OpenGLRenderer::resume() { - const Snapshot* snapshot = currentSnapshot(); - glViewport(0, 0, getViewportWidth(), getViewportHeight()); - glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); - debugOverdraw(true, false); - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - mCaches.scissorEnabled = glIsEnabled(GL_SCISSOR_TEST); - mCaches.enableScissor(); - mCaches.resetScissor(); - dirtyClip(); - - mCaches.activeTexture(0); - mCaches.resetBoundTextures(); - - mCaches.blend = true; - glEnable(GL_BLEND); - glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode); - glBlendEquation(GL_FUNC_ADD); -} - void OpenGLRenderer::resumeAfterLayer() { - glViewport(0, 0, getViewportWidth(), getViewportHeight()); - glBindFramebuffer(GL_FRAMEBUFFER, currentSnapshot()->fbo); + mRenderState.setViewport(getViewportWidth(), getViewportHeight()); + mRenderState.bindFramebuffer(currentSnapshot()->fbo); debugOverdraw(true, false); mCaches.resetScissor(); @@ -379,20 +345,19 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { info.height = getViewportHeight(); currentTransform()->copyTo(&info.transform[0]); - bool dirtyClip = mDirtyClip; + bool prevDirtyClip = mDirtyClip; // setup GL state for functor if (mDirtyClip) { setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt() } - if (mCaches.enableScissor() || dirtyClip) { + if (mCaches.enableScissor() || prevDirtyClip) { setScissorFromClip(); } - interrupt(); - // call functor immediately after GL state setup - (*functor)(DrawGlInfo::kModeDraw, &info); + mRenderState.invokeFunctor(functor, DrawGlInfo::kModeDraw, &info); + // Scissor may have been modified, reset dirty clip + dirtyClip(); - resume(); return DrawGlInfo::kStatusDrew; } @@ -413,17 +378,7 @@ void OpenGLRenderer::endMark() const { } void OpenGLRenderer::debugOverdraw(bool enable, bool clear) { - if (mCaches.debugOverdraw && getTargetFbo() == 0) { - if (clear) { - mCaches.disableScissor(); - mCaches.stencil.clear(); - } - if (enable) { - mCaches.stencil.enableDebugWrite(); - } else { - mCaches.stencil.disable(); - } - } + mRenderState.debugOverdraw(enable, clear); } void OpenGLRenderer::renderOverdraw() { @@ -474,8 +429,8 @@ void OpenGLRenderer::countOverdraw() { /////////////////////////////////////////////////////////////////////////////// bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) { - if (layer->deferredUpdateScheduled && layer->renderer && - layer->displayList.get() && layer->displayList->isRenderable()) { + if (layer->deferredUpdateScheduled && layer->renderer + && layer->renderNode.get() && layer->renderNode->isRenderable()) { ATRACE_CALL(); Rect& dirty = layer->dirtyRect; @@ -528,7 +483,7 @@ void OpenGLRenderer::updateLayers() { if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { mLayerUpdates.clear(); - glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo()); + mRenderState.bindFramebuffer(getTargetFbo()); } endMark(); } @@ -556,7 +511,7 @@ void OpenGLRenderer::flushLayers() { } mLayerUpdates.clear(); - glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo()); + mRenderState.bindFramebuffer(getTargetFbo()); endMark(); } @@ -620,7 +575,7 @@ void OpenGLRenderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& bool restoreLayer = removed.flags & Snapshot::kFlagIsLayer; if (restoreViewport) { - glViewport(0, 0, getViewportWidth(), getViewportHeight()); + mRenderState.setViewport(getViewportWidth(), getViewportHeight()); } if (restoreClip) { @@ -791,7 +746,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto } mCaches.activeTexture(0); - Layer* layer = mCaches.layerCache.get(bounds.getWidth(), bounds.getHeight()); + Layer* layer = mCaches.layerCache.get(mRenderState, bounds.getWidth(), bounds.getHeight()); if (!layer) { return false; } @@ -853,7 +808,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { endTiling(); debugOverdraw(false, false); // Bind texture to FBO - glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo()); + mRenderState.bindFramebuffer(layer->getFbo()); layer->bindTexture(); // Initialize the texture if needed @@ -876,7 +831,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { dirtyClip(); // Change the ortho projection - glViewport(0, 0, bounds.getWidth(), bounds.getHeight()); + mRenderState.setViewport(bounds.getWidth(), bounds.getHeight()); return true; } @@ -907,7 +862,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto layer->removeFbo(false); // Unbind current FBO and restore previous one - glBindFramebuffer(GL_FRAMEBUFFER, restored.fbo); + mRenderState.bindFramebuffer(restored.fbo); debugOverdraw(true, false); startTilingCurrentClip(); @@ -1931,25 +1886,24 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { // Drawing /////////////////////////////////////////////////////////////////////////////// -status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty, - int32_t replayFlags) { +status_t OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) { status_t status; // All the usual checks and setup operations (quickReject, setupDraw, etc.) // will be performed by the display list itself - if (displayList && displayList->isRenderable()) { + if (renderNode && renderNode->isRenderable()) { // compute 3d ordering - displayList->computeOrdering(); + renderNode->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { status = startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); - displayList->replayNodeTree(replayStruct); + renderNode->replay(replayStruct, 0); return status | replayStruct.mDrawGlStatus; } bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs! DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw); DeferStateStruct deferStruct(deferredList, *this, replayFlags); - displayList->deferNodeTree(deferStruct); + renderNode->defer(deferStruct, 0); flushLayers(); status = startFrame(); @@ -2043,10 +1997,10 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float to return DrawGlInfo::kStatusDrew; } -status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix, +status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix, const SkPaint* paint) { Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height()); - const mat4 transform(*matrix); + const mat4 transform(matrix); transform.mapRect(r); if (quickRejectSetupScissor(r.left, r.top, r.right, r.bottom)) { @@ -2556,8 +2510,8 @@ status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float return drawShape(left, top, texture, p); } - const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect(*currentTransform(), - right - left, bottom - top, rx, ry, p); + const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect( + *currentTransform(), *p, right - left, bottom - top, rx, ry); return drawVertexBuffer(left, top, *vertexBuffer, p); } @@ -2611,10 +2565,6 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto return DrawGlInfo::kStatusDone; } - if (fabs(sweepAngle) >= 360.0f) { - return drawOval(left, top, right, bottom, p); - } - // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180) if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || useCenter) { mCaches.activeTexture(0); |