diff options
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
-rwxr-xr-x | libs/hwui/OpenGLRenderer.cpp | 759 |
1 files changed, 390 insertions, 369 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 355a31f..3c8fb8b 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -36,15 +36,19 @@ #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" #include "Fence.h" -#include "RenderState.h" +#include "GammaFontRenderer.h" +#include "Patch.h" #include "PathTessellator.h" #include "Properties.h" +#include "RenderNode.h" +#include "RenderState.h" #include "ShadowTessellator.h" #include "SkiaShader.h" -#include "utils/GLUtils.h" -#include "utils/TraceUtils.h" #include "Vector.h" #include "VertexBuffer.h" +#include "utils/GLUtils.h" +#include "utils/PaintUtils.h" +#include "utils/TraceUtils.h" #if DEBUG_DETAILED_EVENTS #define EVENT_LOGD(...) eventMarkDEBUG(__VA_ARGS__) @@ -130,13 +134,15 @@ static inline T min(T a, T b) { /////////////////////////////////////////////////////////////////////////////// OpenGLRenderer::OpenGLRenderer(RenderState& renderState) - : mFrameStarted(false) + : mState(*this) + , mFrameStarted(false) , mCaches(Caches::getInstance()) , mExtensions(Extensions::getInstance()) , mRenderState(renderState) , mScissorOptimizationDisabled(false) , mSuppressTiling(false) , mFirstFrameAfterResize(true) + , mDirty(false) , mLightCenter((Vector3){FLT_MIN, FLT_MIN, FLT_MIN}) , mLightRadius(FLT_MIN) , mAmbientShadowAlpha(0) @@ -187,20 +193,20 @@ void OpenGLRenderer::onViewportInitialized() { void OpenGLRenderer::setupFrameState(float left, float top, float right, float bottom, bool opaque) { mCaches.clearGarbage(); - initializeSaveStack(left, top, right, bottom, mLightCenter); + mState.initializeSaveStack(left, top, right, bottom, mLightCenter); mOpaque = opaque; mTilingClip.set(left, top, right, bottom); } -status_t OpenGLRenderer::startFrame() { - if (mFrameStarted) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::startFrame() { + if (mFrameStarted) return; mFrameStarted = true; - mDirtyClip = true; + mState.setDirtyClip(true); discardFramebuffer(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom); - mRenderState.setViewport(getWidth(), getHeight()); + mRenderState.setViewport(mState.getWidth(), mState.getHeight()); // Functors break the tiling extension in pretty spectacular ways // This ensures we don't use tiling when a functor is going to be @@ -213,11 +219,11 @@ status_t OpenGLRenderer::startFrame() { debugOverdraw(true, true); - return clear(mTilingClip.left, mTilingClip.top, + clear(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom, mOpaque); } -status_t OpenGLRenderer::prepareDirty(float left, float top, +void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { setupFrameState(left, top, right, bottom, opaque); @@ -230,10 +236,8 @@ status_t OpenGLRenderer::prepareDirty(float left, float top, syncState(); updateLayers(); } else { - return startFrame(); + startFrame(); } - - return DrawGlInfo::kStatusDone; } void OpenGLRenderer::discardFramebuffer(float left, float top, float right, float bottom) { @@ -241,8 +245,8 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa // perform a discard to let the driver know we don't need to preserve // the back buffer for this frame. if (mExtensions.hasDiscardFramebuffer() && - left <= 0.0f && top <= 0.0f && right >= getWidth() && bottom >= getHeight()) { - const bool isFbo = getTargetFbo() == 0; + left <= 0.0f && top <= 0.0f && right >= mState.getWidth() && bottom >= mState.getHeight()) { + const bool isFbo = onGetTargetFbo() == 0; const GLenum attachments[] = { isFbo ? (const GLenum) GL_COLOR_EXT : (const GLenum) GL_COLOR_ATTACHMENT0, isFbo ? (const GLenum) GL_STENCIL_EXT : (const GLenum) GL_STENCIL_ATTACHMENT }; @@ -250,16 +254,16 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa } } -status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { +void OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { if (!opaque) { mCaches.enableScissor(); mCaches.setScissor(left, getViewportHeight() - bottom, right - left, bottom - top); glClear(GL_COLOR_BUFFER_BIT); - return DrawGlInfo::kStatusDrew; + mDirty = true; + return; } mCaches.resetScissor(); - return DrawGlInfo::kStatusDone; } void OpenGLRenderer::syncState() { @@ -307,18 +311,14 @@ void OpenGLRenderer::endTiling() { if (!mSuppressTiling) mCaches.endTiling(); } -void OpenGLRenderer::finish() { +bool OpenGLRenderer::finish() { renderOverdraw(); endTiling(); - - for (size_t i = 0; i < mTempPaths.size(); i++) { - delete mTempPaths[i]; - } mTempPaths.clear(); // When finish() is invoked on FBO 0 we've reached the end // of the current frame - if (getTargetFbo() == 0) { + if (onGetTargetFbo() == 0) { mCaches.pathCache.trim(); mCaches.tessellationCache.trim(); } @@ -338,6 +338,8 @@ void OpenGLRenderer::finish() { } mFrameStarted = false; + + return reportAndClearDirty(); } void OpenGLRenderer::resumeAfterLayer() { @@ -349,10 +351,10 @@ void OpenGLRenderer::resumeAfterLayer() { dirtyClip(); } -status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { + if (mState.currentlyIgnored()) return; - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); // Since we don't know what the functor will draw, let's dirty @@ -371,9 +373,9 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { info.height = getViewportHeight(); currentTransform()->copyTo(&info.transform[0]); - bool prevDirtyClip = mDirtyClip; + bool prevDirtyClip = mState.getDirtyClip(); // setup GL state for functor - if (mDirtyClip) { + if (mState.getDirtyClip()) { setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt() } if (mCaches.enableScissor() || prevDirtyClip) { @@ -384,7 +386,7 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { // Scissor may have been modified, reset dirty clip dirtyClip(); - return DrawGlInfo::kStatusDrew; + mDirty = true; } /////////////////////////////////////////////////////////////////////////////// @@ -402,8 +404,6 @@ void OpenGLRenderer::eventMarkDEBUG(const char* fmt, ...) const { va_end(ap); eventMark(buf); -#else - (void)fmt; #endif } @@ -425,11 +425,11 @@ void OpenGLRenderer::debugOverdraw(bool enable, bool clear) { } void OpenGLRenderer::renderOverdraw() { - if (mCaches.debugOverdraw && getTargetFbo() == 0) { + if (mCaches.debugOverdraw && onGetTargetFbo() == 0) { const Rect* clip = &mTilingClip; mCaches.enableScissor(); - mCaches.setScissor(clip->left, firstSnapshot()->getViewportHeight() - clip->bottom, + mCaches.setScissor(clip->left, mState.firstSnapshot()->getViewportHeight() - clip->bottom, clip->right - clip->left, clip->bottom - clip->top); // 1x overdraw @@ -505,7 +505,7 @@ void OpenGLRenderer::updateLayers() { if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); } endMark(); } @@ -522,7 +522,7 @@ void OpenGLRenderer::flushLayers() { } mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); endMark(); } @@ -604,9 +604,9 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, // force matrix/clip isolation for layer flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag; - const int count = saveSnapshot(flags); + const int count = mState.saveSnapshot(flags); - if (!currentSnapshot()->isIgnored()) { + if (!mState.currentlyIgnored()) { createLayer(left, top, right, bottom, paint, flags, convexMask); } @@ -619,7 +619,7 @@ void OpenGLRenderer::calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool currentTransform()->mapRect(bounds); // Layers only make sense if they are in the framebuffer's bounds - if (bounds.intersect(*currentClipRect())) { + if (bounds.intersect(*mState.currentClipRect())) { // We cannot work with sub-pixels in this case bounds.snapToPixelBoundaries(); @@ -653,17 +653,17 @@ void OpenGLRenderer::updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize || bounds.getHeight() > mCaches.maxTextureSize || (fboLayer && clip.isEmpty())) { - mSnapshot->empty = fboLayer; + writableSnapshot()->empty = fboLayer; } else { - mSnapshot->invisible = mSnapshot->invisible || (alpha <= 0 && fboLayer); + writableSnapshot()->invisible = writableSnapshot()->invisible || (alpha <= 0 && fboLayer); } } int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom, const SkPaint* paint, int flags) { - const int count = saveSnapshot(flags); + const int count = mState.saveSnapshot(flags); - if (!currentSnapshot()->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) { + if (!mState.currentlyIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) { // initialize the snapshot as though it almost represents an FBO layer so deferred draw // operations will be able to store and restore the current clip and transform info, and // quick rejection will be correct (for display lists) @@ -673,11 +673,11 @@ int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float calculateLayerBoundsAndClip(bounds, clip, true); updateSnapshotIgnoreForLayer(bounds, clip, true, getAlphaDirect(paint)); - if (!currentSnapshot()->isIgnored()) { - mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f); - mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); - mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight()); - mSnapshot->roundRectClipState = NULL; + if (!mState.currentlyIgnored()) { + writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f); + writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom); + writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight()); + writableSnapshot()->roundRectClipState = nullptr; } } @@ -737,10 +737,8 @@ int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float */ bool OpenGLRenderer::createLayer(float left, float top, float right, float bottom, const SkPaint* paint, int flags, const SkPath* convexMask) { - if (kDebugLayers) { - ALOGD("Requesting layer %.2fx%.2f", right - left, bottom - top); - ALOGD("Layer cache size = %d", mCaches.layerCache.getSize()); - } + LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top); + LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize()); const bool fboLayer = flags & SkCanvas::kClipToLayer_SaveFlag; @@ -751,7 +749,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, getAlphaDirect(paint)); // Bail out if we won't draw in this snapshot - if (currentSnapshot()->isIgnored()) { + if (mState.currentlyIgnored()) { return false; } @@ -771,8 +769,8 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto layer->setConvexMask(convexMask); // note: the mask must be cleared before returning to the cache // Save the layer in the snapshot - mSnapshot->flags |= Snapshot::kFlagIsLayer; - mSnapshot->layer = layer; + writableSnapshot()->flags |= Snapshot::kFlagIsLayer; + writableSnapshot()->layer = layer; ATRACE_FORMAT_BEGIN("%ssaveLayer %ux%u", fboLayer ? "" : "unclipped ", @@ -790,7 +788,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto // Unfortunately some drivers will turn the entire target texture black // when reading outside of the window. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layer->getWidth(), layer->getHeight(), - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); layer->setEmpty(false); } @@ -799,7 +797,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto bounds.getWidth(), bounds.getHeight()); // Enqueue the buffer coordinates to clear the corresponding region later - mLayers.push(new Rect(bounds)); + mLayers.push_back(Rect(bounds)); } } @@ -810,13 +808,13 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { layer->clipRect.set(clip); layer->setFbo(mCaches.fboCache.get()); - mSnapshot->region = &mSnapshot->layer->region; - mSnapshot->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer; - mSnapshot->fbo = layer->getFbo(); - mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f); - mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); - mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight()); - mSnapshot->roundRectClipState = NULL; + writableSnapshot()->region = &writableSnapshot()->layer->region; + writableSnapshot()->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer; + writableSnapshot()->fbo = layer->getFbo(); + writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f); + writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom); + writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight()); + writableSnapshot()->roundRectClipState = nullptr; endTiling(); debugOverdraw(false, false); @@ -863,8 +861,8 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto const bool fboLayer = removed.flags & Snapshot::kFlagIsFboLayer; bool clipRequired = false; - calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, - &clipRequired, NULL, false); // safely ignore return, should never be rejected + mState.calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, + &clipRequired, nullptr, false); // safely ignore return, should never be rejected mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); if (fboLayer) { @@ -908,7 +906,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto save(0); // the layer contains screen buffer content that shouldn't be alpha modulated // (and any necessary alpha modulation was handled drawing into the layer) - mSnapshot->alpha = 1.0f; + writableSnapshot()->alpha = 1.0f; composeLayerRect(layer, rect, true); restore(); } @@ -916,12 +914,10 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto dirtyClip(); // Failing to add the layer to the cache should happen only if the layer is too large - layer->setConvexMask(NULL); + layer->setConvexMask(nullptr); if (!mCaches.layerCache.put(layer)) { - if (kDebugLayers) { - ALOGD("Deleting layer"); - } - layer->decStrong(0); + LAYER_LOGD("Deleting layer"); + layer->decStrong(nullptr); } } @@ -1018,13 +1014,13 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) * operations are correctly counted twice for overdraw. NOTE: assumes composeLayerRegion only used * by saveLayer's restore */ -#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \ - DRAW_COMMAND; \ - if (CC_UNLIKELY(mCaches.debugOverdraw && getTargetFbo() == 0 && COND)) { \ - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \ - DRAW_COMMAND; \ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \ - } \ +#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \ + DRAW_COMMAND; \ + if (CC_UNLIKELY(mCaches.debugOverdraw && onGetTargetFbo() == 0 && COND)) { \ + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \ + DRAW_COMMAND; \ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \ + } \ } #define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND) @@ -1038,14 +1034,14 @@ public: , mLayer(layer) { } - virtual bool asACustomShader(void** data) const { + virtual bool asACustomShader(void** data) const override { if (data) { *data = static_cast<void*>(mLayer); } return true; } - virtual bool isOpaque() const { + virtual bool isOpaque() const override { return !mLayer->isBlend(); } @@ -1054,13 +1050,13 @@ protected: LOG_ALWAYS_FATAL("LayerShader should never be drawn with raster backend."); } - virtual void flatten(SkWriteBuffer&) const { + virtual void flatten(SkWriteBuffer&) const override { LOG_ALWAYS_FATAL("LayerShader should never be flattened."); } - virtual Factory getFactory() const { + virtual Factory getFactory() const override { LOG_ALWAYS_FATAL("LayerShader should never be created from a stream."); - return NULL; + return nullptr; } private: // Unowned. @@ -1093,7 +1089,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { const SkPath* maskPath = layer->getConvexMask(); DRAW_DOUBLE_STENCIL(drawConvexPath(*maskPath, &paint)); - paint.setShader(NULL); + paint.setShader(nullptr); restore(); return; @@ -1174,7 +1170,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { if (numQuads >= gMaxNumberOfQuads) { DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6, - GL_UNSIGNED_SHORT, NULL)); + GL_UNSIGNED_SHORT, nullptr)); numQuads = 0; mesh = mCaches.getRegionMesh(); } @@ -1182,7 +1178,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { if (numQuads > 0) { DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6, - GL_UNSIGNED_SHORT, NULL)); + GL_UNSIGNED_SHORT, nullptr)); } #if DEBUG_LAYERS_AS_REGIONS @@ -1253,7 +1249,7 @@ void OpenGLRenderer::dirtyLayer(const float left, const float top, } void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) { - if (bounds.intersect(*currentClipRect())) { + if (bounds.intersect(*mState.currentClipRect())) { bounds.snapToPixelBoundaries(); android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom); if (!dirty.isEmpty()) { @@ -1268,7 +1264,7 @@ void OpenGLRenderer::issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount) { GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6); setupDrawIndexedVertices(&mesh[0].x); - glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL); + glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, nullptr); elementsCount -= drawCount; // Though there are 4 vertices in a quad, we use 6 indices per @@ -1281,7 +1277,7 @@ void OpenGLRenderer::clearLayerRegions() { const size_t count = mLayers.size(); if (count == 0) return; - if (!currentSnapshot()->isIgnored()) { + if (!mState.currentlyIgnored()) { EVENT_LOGD("clearLayerRegions"); // Doing several glScissor/glClear here can negatively impact // GPUs with a tiler architecture, instead we draw quads with @@ -1296,14 +1292,12 @@ void OpenGLRenderer::clearLayerRegions() { Vertex* vertex = mesh; for (uint32_t i = 0; i < count; i++) { - Rect* bounds = mLayers.itemAt(i); + const Rect& bounds = mLayers[i]; - Vertex::set(vertex++, bounds->left, bounds->top); - Vertex::set(vertex++, bounds->right, bounds->top); - Vertex::set(vertex++, bounds->left, bounds->bottom); - Vertex::set(vertex++, bounds->right, bounds->bottom); - - delete bounds; + Vertex::set(vertex++, bounds.left, bounds.top); + Vertex::set(vertex++, bounds.right, bounds.top); + Vertex::set(vertex++, bounds.left, bounds.bottom); + Vertex::set(vertex++, bounds.right, bounds.bottom); } // We must clear the list of dirty rects before we // call setupDraw() to prevent stencil setup to do @@ -1325,9 +1319,6 @@ void OpenGLRenderer::clearLayerRegions() { if (scissorChanged) mCaches.enableScissor(); } else { - for (uint32_t i = 0; i < count; i++) { - delete mLayers.itemAt(i); - } mLayers.clear(); } } @@ -1337,7 +1328,7 @@ void OpenGLRenderer::clearLayerRegions() { /////////////////////////////////////////////////////////////////////////////// bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) { - const Rect* currentClip = currentClipRect(); + const Rect* currentClip = mState.currentClipRect(); const mat4* currentMatrix = currentTransform(); if (stateDeferFlags & kStateDeferFlag_Draw) { @@ -1390,12 +1381,12 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) { setMatrix(state.mMatrix); - mSnapshot->alpha = state.mAlpha; + writableSnapshot()->alpha = state.mAlpha; mDrawModifiers = state.mDrawModifiers; - mSnapshot->roundRectClipState = state.mRoundRectClipState; + writableSnapshot()->roundRectClipState = state.mRoundRectClipState; if (state.mClipValid && !skipClipRestore) { - mSnapshot->setClip(state.mClip.left, state.mClip.top, + writableSnapshot()->setClip(state.mClip.left, state.mClip.top, state.mClip.right, state.mClip.bottom); dirtyClip(); } @@ -1409,13 +1400,13 @@ void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool * This method should be called when restoreDisplayState() won't be restoring the clip */ void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) { - if (clipRect != NULL) { - mSnapshot->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); + if (clipRect != nullptr) { + writableSnapshot()->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); } else { - mSnapshot->setClip(0, 0, getWidth(), getHeight()); + writableSnapshot()->setClip(0, 0, mState.getWidth(), mState.getHeight()); } dirtyClip(); - mCaches.setScissorEnabled(clipRect != NULL || mScissorOptimizationDisabled); + mCaches.setScissorEnabled(clipRect != nullptr || mScissorOptimizationDisabled); } /////////////////////////////////////////////////////////////////////////////// @@ -1423,12 +1414,12 @@ void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) { /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setScissorFromClip() { - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); if (mCaches.setScissor(clip.left, getViewportHeight() - clip.bottom, clip.getWidth(), clip.getHeight())) { - mDirtyClip = false; + mState.setDirtyClip(false); } } @@ -1464,7 +1455,7 @@ void OpenGLRenderer::setStencilFromClip() { // NOTE: The order here is important, we must set dirtyClip to false // before any draw call to avoid calling back into this method - mDirtyClip = false; + mState.setDirtyClip(false); ensureStencilBuffer(); @@ -1533,7 +1524,7 @@ bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, bool clipRequired = false; bool roundRectClipRequired = false; - if (calculateQuickRejectForScissor(left, top, right, bottom, + if (mState.calculateQuickRejectForScissor(left, top, right, bottom, &clipRequired, &roundRectClipRequired, snapOut)) { return true; } @@ -1565,7 +1556,7 @@ void OpenGLRenderer::setupDraw(bool clearLayer) { if (clearLayer) clearLayerRegions(); // Make sure setScissor & setStencil happen at the beginning of // this method - if (mDirtyClip) { + if (mState.getDirtyClip()) { if (mCaches.scissorEnabled) { setScissorFromClip(); } @@ -1644,21 +1635,21 @@ void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) { } void OpenGLRenderer::setupDrawShader(const SkShader* shader) { - if (shader != NULL) { + if (shader != nullptr) { SkiaShader::describe(&mCaches, mDescription, mExtensions, *shader); } } void OpenGLRenderer::setupDrawColorFilter(const SkColorFilter* filter) { - if (filter == NULL) { + if (filter == nullptr) { return; } SkXfermode::Mode mode; - if (filter->asColorMode(NULL, &mode)) { + if (filter->asColorMode(nullptr, &mode)) { mDescription.colorOp = ProgramDescription::kColorBlend; mDescription.colorMode = mode; - } else if (filter->asColorMatrix(NULL)) { + } else if (filter->asColorMatrix(nullptr)) { mDescription.colorOp = ProgramDescription::kColorMatrix; } } @@ -1677,8 +1668,10 @@ void OpenGLRenderer::setupDrawBlending(const Layer* layer, bool swapSrcDst) { // argb=1,0,0,0 accountForClear(mode); // TODO: check shader blending, once we have shader drawing support for layers. - bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f || - (mColorSet && mColorA < 1.0f) || isBlendedColorFilter(layer->getColorFilter()); + bool blend = layer->isBlend() + || getLayerAlpha(layer) < 1.0f + || (mColorSet && mColorA < 1.0f) + || PaintUtils::isBlendedColorFilter(layer->getColorFilter()); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -1689,7 +1682,7 @@ void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool sw accountForClear(mode); blend |= (mColorSet && mColorA < 1.0f) || (getShader(paint) && !getShader(paint)->isOpaque()) || - isBlendedColorFilter(getColorFilter(paint)); + PaintUtils::isBlendedColorFilter(getColorFilter(paint)); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -1697,7 +1690,7 @@ void OpenGLRenderer::setupDrawProgram() { useProgram(mCaches.programCache.get(mDescription)); if (mDescription.hasRoundRectClip) { // TODO: avoid doing this repeatedly, stashing state pointer in program - const RoundRectClipState* state = mSnapshot->roundRectClipState; + const RoundRectClipState* state = writableSnapshot()->roundRectClipState; const Rect& innerRect = state->innerRect; glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"), innerRect.left, innerRect.top, @@ -1725,7 +1718,8 @@ void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, bool dirty = right - left > 0.0f && bottom - top > 0.0f; const Matrix4& transformMatrix = ignoreTransform ? Matrix4::identity() : *currentTransform(); - mCaches.currentProgram->set(mSnapshot->getOrthoMatrix(), mModelViewMatrix, transformMatrix, offset); + mCaches.currentProgram->set(writableSnapshot()->getOrthoMatrix(), + mModelViewMatrix, transformMatrix, offset); if (dirty && mTrackDirtyRegions) { if (!ignoreTransform) { dirtyLayer(left, top, right, bottom, *currentTransform()); @@ -1748,7 +1742,7 @@ void OpenGLRenderer::setupDrawPureColorUniforms() { } void OpenGLRenderer::setupDrawShaderUniforms(const SkShader* shader, bool ignoreTransform) { - if (shader == NULL) { + if (shader == nullptr) { return; } @@ -1766,7 +1760,7 @@ void OpenGLRenderer::setupDrawShaderUniforms(const SkShader* shader, bool ignore } void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) { - if (NULL == filter) { + if (nullptr == filter) { return; } @@ -1814,7 +1808,7 @@ void OpenGLRenderer::setupDrawTextGammaUniforms() { void OpenGLRenderer::setupDrawSimpleMesh() { bool force = mCaches.bindMeshBuffer(); - mCaches.bindPositionVertexPointer(force, 0); + mCaches.bindPositionVertexPointer(force, nullptr); mCaches.unbindIndicesBuffer(); } @@ -1903,39 +1897,39 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { // Drawing /////////////////////////////////////////////////////////////////////////////// -status_t OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) { - status_t status; +void OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) { // All the usual checks and setup operations (quickReject, setupDraw, etc.) // will be performed by the display list itself if (renderNode && renderNode->isRenderable()) { // compute 3d ordering renderNode->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { - status = startFrame(); + startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); renderNode->replay(replayStruct, 0); - return status | replayStruct.mDrawGlStatus; + return; } // Don't avoid overdraw when visualizing, since that makes it harder to // debug where it's coming from, and when the problem occurs. bool avoidOverdraw = !mCaches.debugOverdraw; - DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw); + DeferredDisplayList deferredList(*mState.currentClipRect(), avoidOverdraw); DeferStateStruct deferStruct(deferredList, *this, replayFlags); renderNode->defer(deferStruct, 0); flushLayers(); - status = startFrame(); + startFrame(); - return deferredList.flush(*this, dirty) | status; + deferredList.flush(*this, dirty); + } else { + // Even if there is no drawing command(Ex: invisible), + // it still needs startFrame to clear buffer and start tiling. + startFrame(); } - - // Even if there is no drawing command(Ex: invisible), - // it still needs startFrame to clear buffer and start tiling. - return startFrame(); } -void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint) { +void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, + const SkPaint* paint) { float x = left; float y = top; @@ -1955,7 +1949,7 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, co // No need to check for a UV mapper on the texture object, only ARGB_8888 // bitmaps get packed in the atlas drawAlpha8TextureMesh(x, y, x + texture->width, y + texture->height, texture->id, - paint, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, + paint, (GLvoid*) nullptr, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform); } @@ -1964,12 +1958,12 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, co * will not set the scissor enable or dirty the current layer, if any. * The caller is responsible for properly dirtying the current layer. */ -status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, +void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); @@ -1990,17 +1984,17 @@ status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* kModelViewMode_Translate, false); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { +void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); Texture* texture = getTexture(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) { @@ -2009,12 +2003,12 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { +void OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); @@ -2027,13 +2021,13 @@ status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* p drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, +void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { - if (!vertices || currentSnapshot()->isIgnored()) { - return DrawGlInfo::kStatusDone; + if (!vertices || mState.currentlyIgnored()) { + return; } // TODO: use quickReject on bounds from vertices @@ -2046,17 +2040,15 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i const uint32_t count = meshWidth * meshHeight * 6; - Vector<ColorTextureVertex> mesh; // TODO: use C++11 unique_ptr - mesh.setCapacity(count); - ColorTextureVertex* vertex = mesh.editArray(); + std::unique_ptr<ColorTextureVertex[]> mesh(new ColorTextureVertex[count]); + ColorTextureVertex* vertex = &mesh[0]; - bool cleanupColors = false; + std::unique_ptr<int[]> tempColors; if (!colors) { uint32_t colorsCount = (meshWidth + 1) * (meshHeight + 1); - int* newColors = new int[colorsCount]; - memset(newColors, 0xff, colorsCount * sizeof(int)); - colors = newColors; - cleanupColors = true; + tempColors.reset(new int[colorsCount]); + memset(tempColors.get(), 0xff, colorsCount * sizeof(int)); + colors = tempColors.get(); } mCaches.activeTexture(0); @@ -2099,15 +2091,13 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i } if (quickRejectSetupScissor(left, top, right, bottom)) { - if (cleanupColors) delete[] colors; - return DrawGlInfo::kStatusDone; + return; } if (!texture) { texture = mCaches.textureCache.get(bitmap); if (!texture) { - if (cleanupColors) delete[] colors; - return DrawGlInfo::kStatusDone; + return; } } const AutoTexture autoCleanup(texture); @@ -2145,22 +2135,20 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i glDisableVertexAttribArray(slot); } - if (cleanupColors) delete[] colors; - - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, +void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); Texture* texture = getTexture(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float width = texture->width; @@ -2234,33 +2222,33 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, +void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap); const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(), right - left, bottom - top, patch); - return drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); + drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); } -status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, +void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } if (CC_LIKELY(mesh && mesh->verticesCount > 0)) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -2302,7 +2290,7 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /** @@ -2310,11 +2298,11 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, * will not set the scissor enable or dirty the current layer, if any. * The caller is responsible for properly dirtying the current layer. */ -status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, +void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -2324,15 +2312,15 @@ status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* texture->blend, &vertices[0].x, &vertices[0].u, GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, +void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer, const SkPaint* paint, int displayFlags) { // not missing call to quickReject/dirtyLayer, always done at a higher level if (!vertexBuffer.getVertexCount()) { // no vertices to draw - return DrawGlInfo::kStatusDone; + return; } Rect bounds(vertexBuffer.getBounds()); @@ -2345,7 +2333,7 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, setupDraw(); setupDrawNoTexture(); if (isAA) setupDrawVertexAlpha((displayFlags & kVertexBuffer_ShadowInterp)); - setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha); + setupDrawColor(color, ((color >> 24) & 0xFF) * writableSnapshot()->alpha); setupDrawColorFilter(getColorFilter(paint)); setupDrawShader(getShader(paint)); setupDrawBlending(paint, isAA); @@ -2376,21 +2364,23 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount()); } else if (mode == VertexBuffer::kOnePolyRingShadow) { mCaches.bindShadowIndicesBuffer(); - glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); + glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, + GL_UNSIGNED_SHORT, nullptr); } else if (mode == VertexBuffer::kTwoPolyRingShadow) { mCaches.bindShadowIndicesBuffer(); - glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); + glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, + GL_UNSIGNED_SHORT, nullptr); } else if (mode == VertexBuffer::kIndices) { mCaches.unbindIndicesBuffer(); - glDrawElements(GL_TRIANGLE_STRIP, vertexBuffer.getIndexCount(), GL_UNSIGNED_SHORT, - vertexBuffer.getIndices()); + glDrawElements(GL_TRIANGLE_STRIP, vertexBuffer.getIndexCount(), + GL_UNSIGNED_SHORT, vertexBuffer.getIndices()); } if (isAA) { glDisableVertexAttribArray(alphaSlot); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /** @@ -2402,11 +2392,11 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, * * Doesn't yet support joins, caps, or path effects. */ -status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) { +void OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) { VertexBuffer vertexBuffer; // TODO: try clipping large paths to viewport PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer); - return drawVertexBuffer(vertexBuffer, paint); + drawVertexBuffer(vertexBuffer, paint); } /** @@ -2420,8 +2410,8 @@ status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint * TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce * memory transfer by removing need for degenerate vertices. */ -status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored() || count < 4) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) { + if (mState.currentlyIgnored() || count < 4) return; count &= ~0x3; // round down to nearest four @@ -2430,15 +2420,15 @@ status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint const Rect& bounds = buffer.getBounds(); if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) { - return DrawGlInfo::kStatusDone; + return; } int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset; - return drawVertexBuffer(buffer, paint, displayFlags); + drawVertexBuffer(buffer, paint, displayFlags); } -status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored() || count < 2) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { + if (mState.currentlyIgnored() || count < 2) return; count &= ~0x1; // round down to nearest two @@ -2447,18 +2437,20 @@ status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPain const Rect& bounds = buffer.getBounds(); if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) { - return DrawGlInfo::kStatusDone; + return; } int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset; - return drawVertexBuffer(buffer, paint, displayFlags); + drawVertexBuffer(buffer, paint, displayFlags); + + mDirty = true; } -status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { +void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { // No need to check against the clip, we fill the clip region - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; + if (mState.currentlyIgnored()) return; - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); SkPaint paint; @@ -2467,12 +2459,12 @@ status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { drawColorRect(clip.left, clip.top, clip.right, clip.bottom, &paint, true); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, +void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint) { - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float x = left + texture->left - texture->offset; @@ -2480,89 +2472,89 @@ status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* tex drawPathTexture(texture, x, y, paint); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, +void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + || PaintUtils::paintWillNotDraw(*p)) { + return; } - if (p->getPathEffect() != 0) { + if (p->getPathEffect() != nullptr) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getRoundRect( right - left, bottom - top, rx, ry, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + } else { + const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect( + *currentTransform(), *p, right - left, bottom - top, rx, ry); + drawVertexBuffer(left, top, *vertexBuffer, p); } - - const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect( - *currentTransform(), *p, right - left, bottom - top, rx, ry); - return drawVertexBuffer(left, top, *vertexBuffer, p); } -status_t OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) { - if (currentSnapshot()->isIgnored() +void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) { + if (mState.currentlyIgnored() || quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p) - || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + || PaintUtils::paintWillNotDraw(*p)) { + return; } - if (p->getPathEffect() != 0) { + if (p->getPathEffect() != nullptr) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getCircle(radius, p); - return drawShape(x - radius, y - radius, texture, p); - } - - SkPath path; - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - path.addCircle(x, y, radius + p->getStrokeWidth() / 2); + drawShape(x - radius, y - radius, texture, p); } else { - path.addCircle(x, y, radius); + SkPath path; + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + path.addCircle(x, y, radius + p->getStrokeWidth() / 2); + } else { + path.addCircle(x, y, radius); + } + drawConvexPath(path, p); } - return drawConvexPath(path, p); } -status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom, +void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + || PaintUtils::paintWillNotDraw(*p)) { + return; } - if (p->getPathEffect() != 0) { + if (p->getPathEffect() != nullptr) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getOval(right - left, bottom - top, p); - return drawShape(left, top, texture, p); - } - - SkPath path; - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + drawShape(left, top, texture, p); + } else { + SkPath path; + SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + } + path.addOval(rect); + drawConvexPath(path, p); } - path.addOval(rect); - return drawConvexPath(path, p); } -status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom, +void OpenGLRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + || PaintUtils::paintWillNotDraw(*p)) { + return; } // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180) - if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || useCenter) { + if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != nullptr || useCenter) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getArc(right - left, bottom - top, startAngle, sweepAngle, useCenter, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + return; } - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); @@ -2576,46 +2568,47 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto if (useCenter) { path.close(); } - return drawConvexPath(path, p); + drawConvexPath(path, p); } // See SkPaintDefaults.h #define SkPaintDefaults_MiterLimit SkIntToScalar(4) -status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, +void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + || PaintUtils::paintWillNotDraw(*p)) { + return; } if (p->getStyle() != SkPaint::kFill_Style) { // only fill style is supported by drawConvexPath, since others have to handle joins - if (p->getPathEffect() != 0 || p->getStrokeJoin() != SkPaint::kMiter_Join || + if (p->getPathEffect() != nullptr || p->getStrokeJoin() != SkPaint::kMiter_Join || p->getStrokeMiter() != SkPaintDefaults_MiterLimit) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getRect(right - left, bottom - top, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + } else { + SkPath path; + SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + } + path.addRect(rect); + drawConvexPath(path, p); } + } else { + if (p->isAntiAlias() && !currentTransform()->isSimple()) { + SkPath path; + path.addRect(left, top, right, bottom); + drawConvexPath(path, p); + } else { + drawColorRect(left, top, right, bottom, p); - SkPath path; - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + mDirty = true; } - path.addRect(rect); - return drawConvexPath(path, p); - } - - if (p->isAntiAlias() && !currentTransform()->isSimple()) { - SkPath path; - path.addRect(left, top, right, bottom); - return drawConvexPath(path, p); - } else { - drawColorRect(left, top, right, bottom, p); - return DrawGlInfo::kStatusDrew; } } @@ -2642,7 +2635,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, const float sx = x - shadow->left + textShadow.dx; const float sy = y - shadow->top + textShadow.dy; - const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * mSnapshot->alpha; + const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * writableSnapshot()->alpha; if (getShader(paint)) { textShadow.color = SK_ColorWHITE; } @@ -2660,25 +2653,26 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawShaderUniforms(getShader(paint)); - setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); + setupDrawMesh(nullptr, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); } bool OpenGLRenderer::canSkipText(const SkPaint* paint) const { - float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * mSnapshot->alpha; - return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode; + float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha; + return MathUtils::isZero(alpha) + && PaintUtils::getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode; } -status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, +void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint) { - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) { - return DrawGlInfo::kStatusDone; + if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { + return; } // NOTE: Skia does not support perspective transform on drawPosText yet if (!currentTransform()->isSimple()) { - return DrawGlInfo::kStatusDone; + return; } mCaches.enableScissor(); @@ -2710,14 +2704,14 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count } fontRenderer.setTextureFiltering(linearFilter); - const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip(); + const Rect* clip = pureTranslate ? writableSnapshot()->clipRect : &writableSnapshot()->getLocalClip(); Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); const bool hasActiveLayer = hasLayer(); TextSetupFunctor functor(this, x, y, pureTranslate, alpha, mode, paint); if (fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, - positions, hasActiveLayer ? &bounds : NULL, &functor)) { + positions, hasActiveLayer ? &bounds : nullptr, &functor)) { if (hasActiveLayer) { if (!pureTranslate) { currentTransform()->mapRect(bounds); @@ -2726,7 +2720,7 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count } } - return DrawGlInfo::kStatusDrew; + mDirty = true; } bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const { @@ -2750,16 +2744,79 @@ bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outM return true; } -status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, +int OpenGLRenderer::getSaveCount() const { + return mState.getSaveCount(); +} + +int OpenGLRenderer::save(int flags) { + return mState.save(flags); +} + +void OpenGLRenderer::restore() { + return mState.restore(); +} + +void OpenGLRenderer::restoreToCount(int saveCount) { + return mState.restoreToCount(saveCount); +} + +void OpenGLRenderer::translate(float dx, float dy, float dz) { + return mState.translate(dx, dy, dz); +} + +void OpenGLRenderer::rotate(float degrees) { + return mState.rotate(degrees); +} + +void OpenGLRenderer::scale(float sx, float sy) { + return mState.scale(sx, sy); +} + +void OpenGLRenderer::skew(float sx, float sy) { + return mState.skew(sx, sy); +} + +void OpenGLRenderer::setMatrix(const Matrix4& matrix) { + mState.setMatrix(matrix); +} + +void OpenGLRenderer::concatMatrix(const Matrix4& matrix) { + mState.concatMatrix(matrix); +} + +bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { + return mState.clipRect(left, top, right, bottom, op); +} + +bool OpenGLRenderer::clipPath(const SkPath* path, SkRegion::Op op) { + return mState.clipPath(path, op); +} + +bool OpenGLRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { + return mState.clipRegion(region, op); +} + +void OpenGLRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { + mState.setClippingOutline(allocator, outline); +} + +void OpenGLRenderer::setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius, bool highPriority) { + mState.setClippingRoundRect(allocator, rect, radius, highPriority); +} + + + +void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { if (drawOpMode == kDrawOpMode_Immediate) { // The checks for corner-case ignorable text and quick rejection is only done for immediate // drawing as ops from DeferredDisplayList are already filtered for these - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint) || + if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint) || quickRejectSetupScissor(bounds)) { - return DrawGlInfo::kStatusDone; + return; } } @@ -2807,7 +2864,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f fontRenderer.setTextureFiltering(linearFilter); // TODO: Implement better clipping for scaled/rotated text - const Rect* clip = !pureTranslate ? NULL : currentClipRect(); + const Rect* clip = !pureTranslate ? nullptr : mState.currentClipRect(); Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); bool status; @@ -2819,10 +2876,10 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f SkPaint paintCopy(*paint); paintCopy.setTextAlign(SkPaint::kLeft_Align); status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y, - positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish); + positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish); } else { status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, - positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish); + positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish); } if ((status || drawOpMode != kDrawOpMode_Immediate) && hasActiveLayer) { @@ -2834,13 +2891,13 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f drawTextDecorations(totalAdvance, oldX, oldY, paint); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, +void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) { - return DrawGlInfo::kStatusDone; + if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { + return; } // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics @@ -2855,45 +2912,44 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co getAlphaAndMode(paint, &alpha, &mode); TextSetupFunctor functor(this, 0.0f, 0.0f, false, alpha, mode, paint); - const Rect* clip = &mSnapshot->getLocalClip(); + const Rect* clip = &writableSnapshot()->getLocalClip(); Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); const bool hasActiveLayer = hasLayer(); if (fontRenderer.renderTextOnPath(paint, clip, text, 0, bytesCount, count, path, - hOffset, vOffset, hasActiveLayer ? &bounds : NULL, &functor)) { + hOffset, vOffset, hasActiveLayer ? &bounds : nullptr, &functor)) { if (hasActiveLayer) { currentTransform()->mapRect(bounds); dirtyLayerUnchecked(bounds, getRegion()); } } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) { + if (mState.currentlyIgnored()) return; mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.get(path, paint); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float x = texture->left - texture->offset; const float y = texture->top - texture->offset; drawPathTexture(texture, x, y, paint); - - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { +void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { if (!layer) { - return DrawGlInfo::kStatusDone; + return; } - mat4* transform = NULL; + mat4* transform = nullptr; if (layer->isTextureLayer()) { transform = &layer->getTransform(); if (!transform->isIdentity()) { @@ -2903,14 +2959,15 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } bool clipRequired = false; - const bool rejected = calculateQuickRejectForScissor(x, y, - x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired, NULL, false); + const bool rejected = mState.calculateQuickRejectForScissor( + x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), + &clipRequired, nullptr, false); if (rejected) { if (transform && !transform->isIdentity()) { restore(); } - return DrawGlInfo::kStatusDone; + return; } EVENT_LOGD("drawLayer," RECT_STRING ", clipRequired %d", x, y, @@ -2958,7 +3015,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { setupDrawMeshIndices(&mesh[0].x, &mesh[0].u); DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, - glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL)); + glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, nullptr)); elementsCount -= drawCount; // Though there are 4 vertices in a quad, we use 6 indices per @@ -2985,53 +3042,16 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { restore(); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /////////////////////////////////////////////////////////////////////////////// // Draw filters /////////////////////////////////////////////////////////////////////////////// - -void OpenGLRenderer::resetPaintFilter() { - // when clearing the PaintFilter, the masks should also be cleared for simple DrawModifier - // comparison, see MergingDrawBatch::canMergeWith - mDrawModifiers.mHasDrawFilter = false; - mDrawModifiers.mPaintFilterClearBits = 0; - mDrawModifiers.mPaintFilterSetBits = 0; -} - -void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) { - // TODO: don't bother with boolean, it's redundant with clear/set bits - mDrawModifiers.mHasDrawFilter = true; - mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags; - mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags; -} - -const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) { - // TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp - // to avoid clobbering 0x02 paint flag - - // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. - static const uint32_t sFilterBitmapFlag = 0x02; - - if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) { - return paint; - } - - const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits; - const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits; - - const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits; - mFilteredPaint = *paint; - mFilteredPaint.setFlags(flags); - - // check if paint filter trying to override bitmap filter - if ((clearBits | setBits) & sFilterBitmapFlag) { - mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag - ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel); - } - - return &mFilteredPaint; +void OpenGLRenderer::setDrawFilter(SkDrawFilter* filter) { + // We should never get here since we apply the draw filter when stashing + // the paints in the DisplayList. + LOG_ALWAYS_FATAL("OpenGLRenderer does not directly support DrawFilters"); } /////////////////////////////////////////////////////////////////////////////// @@ -3069,7 +3089,7 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawShaderUniforms(getShader(paint)); - setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); + setupDrawMesh(nullptr, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); } @@ -3124,17 +3144,17 @@ void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y, } } -status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored()) { - return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { + if (mState.currentlyIgnored()) { + return; } - return drawColorRects(rects, count, paint, false, true, true); + drawColorRects(rects, count, paint, false, true, true); } -status_t OpenGLRenderer::drawShadow(float casterAlpha, +void OpenGLRenderer::drawShadow(float casterAlpha, const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; + if (mState.currentlyIgnored()) return; // TODO: use quickRejectWithScissor. For now, always force enable scissor. mCaches.enableScissor(); @@ -3161,13 +3181,13 @@ status_t OpenGLRenderer::drawShadow(float casterAlpha, drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp); } - return DrawGlInfo::kStatusDrew; + mDirty=true; } -status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint, +void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint, bool ignoreTransform, bool dirty, bool clip) { if (count == 0) { - return DrawGlInfo::kStatusDone; + return; } int color = paint->getColor(); @@ -3202,7 +3222,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP } if (clip && quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } setupDraw(); @@ -3225,7 +3245,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP issueIndexedQuadDraw(&mesh[0], count / 4); - return DrawGlInfo::kStatusDrew; + mDirty = true; } void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, @@ -3257,7 +3277,7 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b Texture* texture, const SkPaint* paint) { texture->setWrap(GL_CLAMP_TO_EDGE, true); - GLvoid* vertices = (GLvoid*) NULL; + GLvoid* vertices = (GLvoid*) nullptr; GLvoid* texCoords = (GLvoid*) gMeshTextureOffset; if (texture->uvMapper) { @@ -3340,7 +3360,7 @@ void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawMeshIndices(vertices, texCoords, vbo); - glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, NULL); + glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, nullptr); } void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom, @@ -3348,14 +3368,14 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount, bool ignoreTransform, ModelViewMode modelViewMode, bool dirty) { - int color = paint != NULL ? paint->getColor() : 0; + int color = paint != nullptr ? paint->getColor() : 0; int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); setupDraw(); setupDrawWithTexture(true); - if (paint != NULL) { + if (paint != nullptr) { setupDrawAlpha8Color(color, alpha); } setupDrawColorFilter(getColorFilter(paint)); @@ -3376,7 +3396,7 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description, bool swapSrcDst) { - if (mSnapshot->roundRectClipState != NULL /*&& !mSkipOutlineClip*/) { + if (writableSnapshot()->roundRectClipState != nullptr /*&& !mSkipOutlineClip*/) { blend = true; mDescription.hasRoundRectClip = true; } @@ -3426,7 +3446,7 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool OpenGLRenderer::useProgram(Program* program) { if (!program->isInUse()) { - if (mCaches.currentProgram != NULL) mCaches.currentProgram->remove(); + if (mCaches.currentProgram != nullptr) mCaches.currentProgram->remove(); program->use(); mCaches.currentProgram = program; return false; @@ -3442,7 +3462,8 @@ void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, flo TextureVertex::setUV(v++, u2, v2); } -void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const { +void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, + SkXfermode::Mode* mode) const { getAlphaAndModeDirect(paint, alpha, mode); if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) { // if drawing a layer, ignore the paint's alpha |