diff options
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 401 |
1 files changed, 233 insertions, 168 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 4d76bed..79df520 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -180,7 +180,21 @@ void OpenGLRenderer::setViewport(int width, int height) { } void OpenGLRenderer::initViewport(int width, int height) { - mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); + float dist = std::max(width, height) * 1.5; + + if (DEBUG_ENABLE_3D) { + // TODO: make view proj app configurable + Matrix4 projection; + projection.loadFrustum(-width / 2, -height / 2, width / 2, height / 2, dist, 0); + Matrix4 view; + view.loadLookAt(0, 0, dist, + 0, 0, 0, + 0, 1, 0); + mViewProjMatrix.loadMultiply(projection, view); + mViewProjMatrix.translate(-width/2, -height/2); + } else { + mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1); + } mWidth = width; mHeight = height; @@ -753,7 +767,7 @@ bool OpenGLRenderer::restoreSnapshot() { if (restoreOrtho) { Rect& r = previous->viewport; glViewport(r.left, r.top, r.right, r.bottom); - mOrthoMatrix.load(current->orthoMatrix); + mViewProjMatrix.load(current->orthoMatrix); } mSaveCount--; @@ -779,11 +793,10 @@ bool OpenGLRenderer::restoreSnapshot() { int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode, int flags) { - const GLuint previousFbo = mSnapshot->fbo; const int count = saveSnapshot(flags); if (!mSnapshot->isIgnored()) { - createLayer(left, top, right, bottom, alpha, mode, flags, previousFbo); + createLayer(left, top, right, bottom, alpha, mode, flags); } return count; @@ -835,7 +848,6 @@ void OpenGLRenderer::updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode, int flags) { - const GLuint previousFbo = mSnapshot->fbo; const int count = saveSnapshot(flags); if (!mSnapshot->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) { @@ -911,7 +923,7 @@ int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float * something actually gets drawn are the layers regions cleared. */ bool OpenGLRenderer::createLayer(float left, float top, float right, float bottom, - int alpha, SkXfermode::Mode mode, int flags, GLuint previousFbo) { + int alpha, SkXfermode::Mode mode, int flags) { LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top); LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize()); @@ -948,7 +960,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto startMark("SaveLayer"); if (fboLayer) { - return createFboLayer(layer, bounds, clip, previousFbo); + return createFboLayer(layer, bounds, clip); } else { // Copy the framebuffer into the layer layer->bindTexture(); @@ -974,7 +986,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto return true; } -bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLuint previousFbo) { +bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { layer->clipRect.set(clip); layer->setFbo(mCaches.fboCache.get()); @@ -986,7 +998,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); mSnapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight()); mSnapshot->height = bounds.getHeight(); - mSnapshot->orthoMatrix.load(mOrthoMatrix); + mSnapshot->orthoMatrix.load(mViewProjMatrix); endTiling(); debugOverdraw(false, false); @@ -1015,7 +1027,9 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui // Change the ortho projection glViewport(0, 0, bounds.getWidth(), bounds.getHeight()); - mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f); + + // TODO: determine best way to support 3d drawing within HW layers + mViewProjMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f); return true; } @@ -1034,7 +1048,8 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer; bool clipRequired = false; - quickRejectNoScissor(rect, &clipRequired); // safely ignore return, should never be rejected + calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, + &clipRequired, false); // safely ignore return, should never be rejected mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); if (fboLayer) { @@ -1122,13 +1137,15 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f); layer->setFilter(GL_NEAREST); - setupDrawModelView(x, y, x + rect.getWidth(), y + rect.getHeight(), true); + setupDrawModelView(kModelViewMode_TranslateAndScale, false, + x, y, x + rect.getWidth(), y + rect.getHeight(), true); } else { layer->setFilter(GL_LINEAR); - setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom); + setupDrawModelView(kModelViewMode_TranslateAndScale, false, + rect.left, rect.top, rect.right, rect.bottom); } setupDrawTextureTransformUniforms(layer->getTexTransform()); - setupDrawMesh(&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]); + setupDrawMesh(&mMeshVertices[0].x, &mMeshVertices[0].u); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); } @@ -1161,7 +1178,7 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) bool blend = layer->isBlend() || alpha < 1.0f; drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(), layer->getTexture(), alpha, layer->getMode(), blend, - &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], + &mMeshVertices[0].x, &mMeshVertices[0].u, GL_TRIANGLE_STRIP, gMeshCount, swap, swap || simpleTransform); resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); @@ -1237,12 +1254,14 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f); layer->setFilter(GL_NEAREST); - setupDrawModelViewTranslate(x, y, x + rect.getWidth(), y + rect.getHeight(), true); + setupDrawModelView(kModelViewMode_Translate, false, + x, y, x + rect.getWidth(), y + rect.getHeight(), true); } else { layer->setFilter(GL_LINEAR); - setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom); + setupDrawModelView(kModelViewMode_Translate, false, + rect.left, rect.top, rect.right, rect.bottom); } - setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]); + setupDrawMeshIndices(&mesh[0].x, &mesh[0].u); for (size_t i = 0; i < count; i++) { const android::Rect* r = &rects[i]; @@ -1274,15 +1293,15 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { } #if DEBUG_LAYERS_AS_REGIONS - drawRegionRects(layer->region); + drawRegionRectsDebug(layer->region); #endif layer->region.clear(); } } -void OpenGLRenderer::drawRegionRects(const Region& region) { #if DEBUG_LAYERS_AS_REGIONS +void OpenGLRenderer::drawRegionRectsDebug(const Region& region) { size_t count; const android::Rect* rects = region.getArray(&count); @@ -1304,8 +1323,8 @@ void OpenGLRenderer::drawRegionRects(const Region& region) { drawColorRect(r.left, r.top, r.right, r.bottom, colors[offset + (i & 0x1)], SkXfermode::kSrcOver_Mode); } -#endif } +#endif void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color, SkXfermode::Mode mode, bool dirty) { @@ -1351,12 +1370,12 @@ void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) { } } -void OpenGLRenderer::drawIndexedQuads(Vertex* mesh, GLsizei quadsCount) { +void OpenGLRenderer::issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount) { GLsizei elementsCount = quadsCount * 6; while (elementsCount > 0) { GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6); - setupDrawIndexedVertices(&mesh[0].position[0]); + setupDrawIndexedVertices(&mesh[0].x); glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL); elementsCount -= drawCount; @@ -1403,9 +1422,10 @@ void OpenGLRenderer::clearLayerRegions() { setupDrawBlending(true, SkXfermode::kClear_Mode); setupDrawProgram(); setupDrawPureColorUniforms(); - setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true); + setupDrawModelView(kModelViewMode_Translate, false, + 0.0f, 0.0f, 0.0f, 0.0f, true); - drawIndexedQuads(&mesh[0], count); + issueIndexedQuadDraw(&mesh[0], count); if (scissorChanged) mCaches.enableScissor(); } else { @@ -1535,10 +1555,8 @@ void OpenGLRenderer::getMatrix(SkMatrix* matrix) { } void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { - SkMatrix transform; - currentTransform().copyTo(transform); - transform.preConcat(*matrix); - currentTransform().load(transform); + mat4 transform(*matrix); + currentTransform().multiply(transform); } /////////////////////////////////////////////////////////////////////////////// @@ -1626,8 +1644,18 @@ const Rect& OpenGLRenderer::getClipBounds() { return mSnapshot->getLocalClip(); } -bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom, - bool snapOut, bool* clipRequired) { +/** + * Calculates whether content drawn within the passed bounds would be outside of, or intersect with + * the clipRect. Does not modify the scissor. + * + * @param clipRequired if not null, will be set to true if element intersects clip + * (and wasn't rejected) + * + * @param snapOut if set, the geometry will be treated as having an AA ramp. + * See Rect::snapGeometryToPixelBoundaries() + */ +bool OpenGLRenderer::calculateQuickRejectForScissor(float left, float top, + float right, float bottom, bool* clipRequired, bool snapOut) const { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { return true; } @@ -1641,31 +1669,65 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl if (!clipRect.intersects(r)) return true; + // clip is required if geometry intersects clip rect if (clipRequired) *clipRequired = !clipRect.contains(r); return false; } -bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, float bottom, +/** + * Returns false if drawing won't be clipped out. + * + * Makes the decision conservatively, by rounding out the mapped rect before comparing with the + * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but + * rejection is still desired. + * + * This function, unlike quickRejectSetupScissor, should be used where precise geometry information + * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass + * rejection where precise rejection isn't important, or precise information isn't available. + */ +bool OpenGLRenderer::quickRejectConservative(float left, float top, + float right, float bottom) const { + if (mSnapshot->isIgnored() || bottom <= top || right <= left) { + return true; + } + + Rect r(left, top, right, bottom); + currentTransform().mapRect(r); + r.roundOut(); // rounded out to be conservative + + Rect clipRect(*mSnapshot->clipRect); + clipRect.snapToPixelBoundaries(); + + if (!clipRect.intersects(r)) return true; + + return false; +} + +/** + * Returns false and sets scissor enable based upon bounds if drawing won't be clipped out. + * + * @param paint if not null, the bounds will be expanded to account for stroke depending on paint + * style, and tessellated AA ramp + */ +bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, float bottom, SkPaint* paint) { - // AA geometry will likely have a ramp around it (not accounted for in local bounds). Snap out - // the final mapped rect to ensure correct clipping behavior for the ramp. - bool snapOut = paint->isAntiAlias(); + bool clipRequired = false; + bool snapOut = paint && paint->isAntiAlias(); - if (paint->getStyle() != SkPaint::kFill_Style) { + if (paint && paint->getStyle() != SkPaint::kFill_Style) { float outset = paint->getStrokeWidth() * 0.5f; - return quickReject(left - outset, top - outset, right + outset, bottom + outset, snapOut); - } else { - return quickReject(left, top, right, bottom, snapOut); + left -= outset; + top -= outset; + right += outset; + bottom += outset; } -} -bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom, bool snapOut) { - bool clipRequired = false; - if (quickRejectNoScissor(left, top, right, bottom, snapOut, &clipRequired)) { + if (calculateQuickRejectForScissor(left, top, right, bottom, &clipRequired, snapOut)) { return true; } if (!isDeferred()) { + // not quick rejected, so enable the scissor if clipRequired mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); } return false; @@ -1740,7 +1802,7 @@ Rect* OpenGLRenderer::getClipRect() { /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setupDraw(bool clear) { - // TODO: It would be best if we could do this before quickReject() + // TODO: It would be best if we could do this before quickRejectSetupScissor() // changes the scissor test state if (clear) clearLayerRegions(); // Make sure setScissor & setStencil happen at the beginning of @@ -1798,7 +1860,7 @@ void OpenGLRenderer::setupDrawColor(int color, int alpha) { mColorG = mColorA * ((color >> 8) & 0xFF) / 255.0f; mColorB = mColorA * ((color ) & 0xFF) / 255.0f; mColorSet = true; - mSetShaderColor = mDescription.setColor(mColorR, mColorG, mColorB, mColorA); + mSetShaderColor = mDescription.setColorModulate(mColorA); } void OpenGLRenderer::setupDrawAlpha8Color(int color, int alpha) { @@ -1807,7 +1869,7 @@ void OpenGLRenderer::setupDrawAlpha8Color(int color, int alpha) { mColorG = mColorA * ((color >> 8) & 0xFF) / 255.0f; mColorB = mColorA * ((color ) & 0xFF) / 255.0f; mColorSet = true; - mSetShaderColor = mDescription.setAlpha8Color(mColorR, mColorG, mColorB, mColorA); + mSetShaderColor = mDescription.setAlpha8ColorModulate(mColorR, mColorG, mColorB, mColorA); } void OpenGLRenderer::setupDrawTextGamma(const SkPaint* paint) { @@ -1820,7 +1882,7 @@ void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) { mColorG = g; mColorB = b; mColorSet = true; - mSetShaderColor = mDescription.setColor(r, g, b, a); + mSetShaderColor = mDescription.setColorModulate(a); } void OpenGLRenderer::setupDrawShader() { @@ -1870,39 +1932,20 @@ void OpenGLRenderer::setupDrawDirtyRegionsDisabled() { mTrackDirtyRegions = false; } -void OpenGLRenderer::setupDrawModelViewTranslate(float left, float top, float right, float bottom, - bool ignoreTransform) { +void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, + float left, float top, float right, float bottom, bool ignoreTransform) { mModelView.loadTranslate(left, top, 0.0f); - if (!ignoreTransform) { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform()); - if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, currentTransform()); - } else { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity()); - if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom); - } -} - -void OpenGLRenderer::setupDrawModelViewIdentity(bool offset) { - mCaches.currentProgram->set(mOrthoMatrix, mat4::identity(), currentTransform(), offset); -} - -void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom, - bool ignoreTransform, bool ignoreModelView) { - if (!ignoreModelView) { - mModelView.loadTranslate(left, top, 0.0f); + if (mode == kModelViewMode_TranslateAndScale) { mModelView.scale(right - left, bottom - top, 1.0f); - } else { - mModelView.loadIdentity(); } + bool dirty = right - left > 0.0f && bottom - top > 0.0f; if (!ignoreTransform) { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform()); - if (mTrackDirtyRegions && dirty) { - dirtyLayer(left, top, right, bottom, currentTransform()); - } + mCaches.currentProgram->set(mViewProjMatrix, mModelView, currentTransform(), offset); + if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, currentTransform()); } else { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity()); - if (mTrackDirtyRegions && dirty) dirtyLayer(left, top, right, bottom); + mCaches.currentProgram->set(mViewProjMatrix, mModelView, mat4::identity(), offset); + if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom); } } @@ -1921,20 +1964,19 @@ void OpenGLRenderer::setupDrawPureColorUniforms() { void OpenGLRenderer::setupDrawShaderUniforms(bool ignoreTransform) { if (mDrawModifiers.mShader) { if (ignoreTransform) { - mModelView.loadInverse(currentTransform()); + // if ignoreTransform=true was passed to setupDrawModelView, undo currentTransform() + // because it was built into modelView / the geometry, and the SkiaShader needs to + // compensate. + mat4 modelViewWithoutTransform; + modelViewWithoutTransform.loadInverse(currentTransform()); + modelViewWithoutTransform.multiply(mModelView); + mModelView.load(modelViewWithoutTransform); } mDrawModifiers.mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &mTextureUnit); } } -void OpenGLRenderer::setupDrawShaderIdentityUniforms() { - if (mDrawModifiers.mShader) { - mDrawModifiers.mShader->setupProgram(mCaches.currentProgram, - mat4::identity(), *mSnapshot, &mTextureUnit); - } -} - void OpenGLRenderer::setupDrawColorFilterUniforms() { if (mDrawModifiers.mColorFilter) { mDrawModifiers.mColorFilter->setupProgram(mCaches.currentProgram); @@ -2036,9 +2078,12 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, 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()) { + // compute 3d ordering + displayList->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { status = startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); @@ -2054,18 +2099,12 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, flushLayers(); status = startFrame(); - return status | deferredList.flush(*this, dirty); + return deferredList.flush(*this, dirty) | status; } return DrawGlInfo::kStatusDone; } -void OpenGLRenderer::outputDisplayList(DisplayList* displayList) { - if (displayList) { - displayList->output(1); - } -} - void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint) { int alpha; SkXfermode::Mode mode; @@ -2118,17 +2157,19 @@ status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry, const float x = (int) floorf(bounds.left + 0.5f); const float y = (int) floorf(bounds.top + 0.5f); - if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) { + if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) { int color = paint != NULL ? paint->getColor() : 0; drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(), texture->id, paint != NULL, color, alpha, mode, - &vertices[0].position[0], &vertices[0].texture[0], - GL_TRIANGLES, bitmapCount * 6, true, true, false); + &vertices[0].x, &vertices[0].u, + GL_TRIANGLES, bitmapCount * 6, true, + kModelViewMode_Translate, false); } else { drawTextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(), texture->id, alpha / 255.0f, mode, texture->blend, - &vertices[0].position[0], &vertices[0].texture[0], - GL_TRIANGLES, bitmapCount * 6, false, true, 0, true, false); + &vertices[0].x, &vertices[0].u, + GL_TRIANGLES, bitmapCount * 6, false, true, 0, + kModelViewMode_Translate, false); } return DrawGlInfo::kStatusDrew; @@ -2138,7 +2179,7 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkP const float right = left + bitmap->width(); const float bottom = top + bitmap->height(); - if (quickReject(left, top, right, bottom)) { + if (quickRejectSetupScissor(left, top, right, bottom)) { return DrawGlInfo::kStatusDone; } @@ -2147,7 +2188,7 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkP if (!texture) return DrawGlInfo::kStatusDone; const AutoTexture autoCleanup(texture); - if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) { + if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) { drawAlphaBitmap(texture, left, top, paint); } else { drawTextureRect(left, top, right, bottom, texture, paint); @@ -2161,7 +2202,7 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* const mat4 transform(*matrix); transform.mapRect(r); - if (quickReject(r.left, r.top, r.right, r.bottom)) { + if (quickRejectSetupScissor(r.left, r.top, r.right, r.bottom)) { return DrawGlInfo::kStatusDone; } @@ -2174,7 +2215,7 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* // to the vertex shader. The save/restore is a bit overkill. save(SkCanvas::kMatrix_SaveFlag); concatMatrix(matrix); - if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) { + if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) { drawAlphaBitmap(texture, 0.0f, 0.0f, paint); } else { drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint); @@ -2188,7 +2229,7 @@ status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, const float right = left + bitmap->width(); const float bottom = top + bitmap->height(); - if (quickReject(left, top, right, bottom)) { + if (quickRejectSetupScissor(left, top, right, bottom)) { return DrawGlInfo::kStatusDone; } @@ -2196,7 +2237,7 @@ status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, Texture* texture = mCaches.textureCache.getTransient(bitmap); const AutoTexture autoCleanup(texture); - if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) { + if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) { drawAlphaBitmap(texture, left, top, paint); } else { drawTextureRect(left, top, right, bottom, texture, paint); @@ -2271,7 +2312,7 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes } } - if (quickReject(left, top, right, bottom)) { + if (quickRejectSetupScissor(left, top, right, bottom)) { if (cleanupColors) delete[] colors; return DrawGlInfo::kStatusDone; } @@ -2305,11 +2346,11 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes setupDrawBlending(true, mode, false); setupDrawProgram(); setupDrawDirtyRegionsDisabled(); - setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, false); + setupDrawModelView(kModelViewMode_TranslateAndScale, false, 0.0f, 0.0f, 1.0f, 1.0f); setupDrawTexture(texture->id); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(); - setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0], &mesh[0].color[0]); + setupDrawMesh(&mesh[0].x, &mesh[0].u, &mesh[0].r); glDrawArrays(GL_TRIANGLES, 0, count); @@ -2327,7 +2368,7 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { - if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) { + if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) { return DrawGlInfo::kStatusDone; } @@ -2393,16 +2434,16 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, dstBottom = srcBottom - srcTop; } - if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) { + if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) { int color = paint ? paint->getColor() : 0; drawAlpha8TextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, paint != NULL, color, alpha, mode, - &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], + &mMeshVertices[0].x, &mMeshVertices[0].u, GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform); } else { drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f, mode, texture->blend, - &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], + &mMeshVertices[0].x, &mMeshVertices[0].u, GL_TRIANGLE_STRIP, gMeshCount, false, ignoreTransform); } @@ -2417,7 +2458,7 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, float left, float top, float right, float bottom, SkPaint* paint) { - if (quickReject(left, top, right, bottom)) { + if (quickRejectSetupScissor(left, top, right, bottom)) { return DrawGlInfo::kStatusDone; } @@ -2430,7 +2471,7 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, SkPaint* paint) { - if (quickReject(left, top, right, bottom)) { + if (quickRejectSetupScissor(left, top, right, bottom)) { return DrawGlInfo::kStatusDone; } @@ -2466,22 +2507,21 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const Patch* mesh, AssetAtl } } + bool ignoreTransform = false; if (CC_LIKELY(pureTranslate)) { const float x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f); const float y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f); right = x + right - left; bottom = y + bottom - top; - drawIndexedTextureMesh(x, y, right, bottom, texture->id, alpha / 255.0f, - mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset, - GL_TRIANGLES, mesh->indexCount, false, true, - mCaches.patchCache.getMeshBuffer(), true, !mesh->hasEmptyQuads); - } else { - drawIndexedTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, - mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset, - GL_TRIANGLES, mesh->indexCount, false, false, - mCaches.patchCache.getMeshBuffer(), true, !mesh->hasEmptyQuads); + left = x; + top = y; + ignoreTransform = true; } + drawIndexedTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, + mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset, + GL_TRIANGLES, mesh->indexCount, false, ignoreTransform, + mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads); } return DrawGlInfo::kStatusDrew; @@ -2507,14 +2547,16 @@ status_t OpenGLRenderer::drawPatches(SkBitmap* bitmap, AssetAtlas::Entry* entry, getAlphaAndMode(paint, &alpha, &mode); drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f, - mode, texture->blend, &vertices[0].position[0], &vertices[0].texture[0], - GL_TRIANGLES, indexCount, false, true, 0, true, false); + mode, texture->blend, &vertices[0].x, &vertices[0].u, + GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false); return DrawGlInfo::kStatusDrew; } status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint, bool useOffset) { + // not missing call to quickReject/dirtyLayer, always done at a higher level + if (!vertexBuffer.getVertexCount()) { // no vertices to draw return DrawGlInfo::kStatusDone; @@ -2532,10 +2574,10 @@ status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPa setupDrawShader(); setupDrawBlending(isAA, mode); setupDrawProgram(); - setupDrawModelViewIdentity(useOffset); + setupDrawModelView(kModelViewMode_Translate, useOffset, 0, 0, 0, 0); setupDrawColorUniforms(); setupDrawColorFilterUniforms(); - setupDrawShaderIdentityUniforms(); + setupDrawShaderUniforms(); void* vertices = vertexBuffer.getBuffer(); bool force = mCaches.unbindMeshBuffer(); @@ -2578,7 +2620,7 @@ status_t OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) { if (hasLayer()) { SkRect bounds = path.getBounds(); - PathTessellator::expandBoundsForStroke(bounds, paint, false); + PathTessellator::expandBoundsForStroke(bounds, paint); dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform()); } @@ -2605,7 +2647,8 @@ status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { SkRect bounds; PathTessellator::tessellateLines(points, count, paint, mSnapshot->transform, bounds, buffer); - if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) { + // can't pass paint, since style would be checked for outset. outset done by tessellation. + if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) { return DrawGlInfo::kStatusDone; } @@ -2624,7 +2667,8 @@ status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { SkRect bounds; PathTessellator::tessellatePoints(points, count, paint, mSnapshot->transform, bounds, buffer); - if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) { + // can't pass paint, since style would be checked for outset. outset done by tessellation. + if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) { return DrawGlInfo::kStatusDone; } @@ -2661,7 +2705,7 @@ status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* tex status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, SkPaint* p) { - if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) || + if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) { return DrawGlInfo::kStatusDone; } @@ -2686,7 +2730,7 @@ status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float } status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) { - if (mSnapshot->isIgnored() || quickRejectPreStroke(x - radius, y - radius, + if (mSnapshot->isIgnored() || quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p) || (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) { return DrawGlInfo::kStatusDone; @@ -2708,7 +2752,7 @@ status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* p) { - if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) || + if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) { return DrawGlInfo::kStatusDone; } @@ -2730,7 +2774,7 @@ status_t OpenGLRenderer::drawOval(float left, float top, float right, float bott status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, SkPaint* p) { - if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) || + if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) { return DrawGlInfo::kStatusDone; } @@ -2767,7 +2811,7 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto #define SkPaintDefaults_MiterLimit SkIntToScalar(4) status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) { - if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) || + if (mSnapshot->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) { return DrawGlInfo::kStatusDone; } @@ -2832,7 +2876,8 @@ void OpenGLRenderer::drawTextShadow(SkPaint* paint, const char* text, int bytesC setupDrawShader(); setupDrawBlending(true, mode); setupDrawProgram(); - setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height); + setupDrawModelView(kModelViewMode_TranslateAndScale, false, + sx, sy, sx + shadow->width, sy + shadow->height); setupDrawTexture(shadow->id); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(); @@ -2930,7 +2975,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f // 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 || mSnapshot->isIgnored() || canSkipText(paint) || - quickReject(bounds)) { + quickRejectSetupScissor(bounds)) { return DrawGlInfo::kStatusDone; } } @@ -3004,7 +3049,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f dirtyLayerUnchecked(layerBounds, getRegion()); } - drawTextDecorations(text, bytesCount, totalAdvance, oldX, oldY, paint); + drawTextDecorations(totalAdvance, oldX, oldY, paint); return DrawGlInfo::kStatusDrew; } @@ -3075,8 +3120,8 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } bool clipRequired = false; - const bool rejected = quickRejectNoScissor(x, y, - x + layer->layer.getWidth(), y + layer->layer.getHeight(), false, &clipRequired); + const bool rejected = calculateQuickRejectForScissor(x, y, + x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired, false); if (rejected) { if (transform && !transform->isIdentity()) { @@ -3113,11 +3158,11 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { int ty = (int) floorf(y + currentTransform().getTranslateY() + 0.5f); layer->setFilter(GL_NEAREST); - setupDrawModelViewTranslate(tx, ty, + setupDrawModelView(kModelViewMode_Translate, false, tx, ty, tx + layer->layer.getWidth(), ty + layer->layer.getHeight(), true); } else { layer->setFilter(GL_LINEAR); - setupDrawModelViewTranslate(x, y, + setupDrawModelView(kModelViewMode_Translate, false, x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight()); } @@ -3127,7 +3172,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { while (elementsCount > 0) { GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6); - setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]); + setupDrawMeshIndices(&mesh[0].x, &mesh[0].u); DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL)); @@ -3138,7 +3183,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } #if DEBUG_LAYERS_AS_REGIONS - drawRegionRects(layer->region); + drawRegionRectsDebug(layer->region); #endif } @@ -3248,7 +3293,7 @@ Texture* OpenGLRenderer::getTexture(SkBitmap* bitmap) { void OpenGLRenderer::drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint) { - if (quickReject(x, y, x + texture->width, y + texture->height)) { + if (quickRejectSetupScissor(x, y, x + texture->width, y + texture->height)) { return; } @@ -3263,7 +3308,8 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, setupDrawShader(); setupDrawBlending(true, mode); setupDrawProgram(); - setupDrawModelView(x, y, x + texture->width, y + texture->height); + setupDrawModelView(kModelViewMode_TranslateAndScale, false, + x, y, x + texture->width, y + texture->height); setupDrawTexture(texture->id); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(); @@ -3278,8 +3324,7 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, #define kStdUnderline_Offset (1.0f / 9.0f) #define kStdUnderline_Thickness (1.0f / 18.0f) -void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float underlineWidth, - float x, float y, SkPaint* paint) { +void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y, SkPaint* paint) { // Handle underline and strike-through uint32_t flags = paint->getFlags(); if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) { @@ -3338,6 +3383,34 @@ status_t OpenGLRenderer::drawRects(const float* rects, int count, SkPaint* paint return drawColorRects(rects, count, color, mode); } +status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlpha, + float width, float height) { + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; + + // For now, always and scissor + // TODO: use quickReject + mCaches.enableScissor(); + + SkPaint paint; + paint.setColor(0x3f000000); + paint.setAntiAlias(true); + VertexBuffer vertexBuffer; + { + //TODO: populate vertex buffer with better shadow geometry. + Vector3 pivot(width/2, height/2, 0.0f); + casterTransform.mapPoint3d(pivot); + + float zScaleFactor = 0.5 + 0.0005f * pivot.z; + + SkPath path; + path.addRect(pivot.x - width * zScaleFactor, pivot.y - height * zScaleFactor, + pivot.x + width * zScaleFactor, pivot.y + height * zScaleFactor); + PathTessellator::tessellatePath(path, &paint, mSnapshot->transform, vertexBuffer); + } + + return drawVertexBuffer(vertexBuffer, &paint); +} + status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color, SkXfermode::Mode mode, bool ignoreTransform, bool dirty, bool clip) { if (count == 0) { @@ -3369,7 +3442,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color bottom = fmaxf(bottom, b); } - if (clip && quickReject(left, top, right, bottom)) { + if (clip && quickRejectSetupScissor(left, top, right, bottom)) { return DrawGlInfo::kStatusDone; } @@ -3381,7 +3454,8 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color setupDrawBlending(mode); setupDrawProgram(); setupDrawDirtyRegionsDisabled(); - setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, ignoreTransform, true); + setupDrawModelView(kModelViewMode_Translate, false, + 0.0f, 0.0f, 0.0f, 0.0f, ignoreTransform); setupDrawColorUniforms(); setupDrawShaderUniforms(); setupDrawColorFilterUniforms(); @@ -3390,7 +3464,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color dirtyLayer(left, top, right, bottom, currentTransform()); } - drawIndexedQuads(&mesh[0], count / 4); + issueIndexedQuadDraw(&mesh[0], count / 4); return DrawGlInfo::kStatusDrew; } @@ -3409,7 +3483,8 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot setupDrawColorFilter(); setupDrawBlending(mode); setupDrawProgram(); - setupDrawModelView(left, top, right, bottom, ignoreTransform); + setupDrawModelView(kModelViewMode_TranslateAndScale, false, + left, top, right, bottom, ignoreTransform); setupDrawColorUniforms(); setupDrawShaderUniforms(ignoreTransform); setupDrawColorFilterUniforms(); @@ -3430,8 +3505,8 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b GLvoid* texCoords = (GLvoid*) gMeshTextureOffset; if (texture->uvMapper) { - vertices = &mMeshVertices[0].position[0]; - texCoords = &mMeshVertices[0].texture[0]; + vertices = &mMeshVertices[0].x; + texCoords = &mMeshVertices[0].u; Rect uvs(0.0f, 0.0f, 1.0f, 1.0f); texture->uvMapper->map(uvs); @@ -3467,7 +3542,8 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount, - bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) { + bool swapSrcDst, bool ignoreTransform, GLuint vbo, + ModelViewMode modelViewMode, bool dirty) { setupDraw(); setupDrawWithTexture(); @@ -3476,11 +3552,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b setupDrawBlending(blend, mode, swapSrcDst); setupDrawProgram(); if (!dirty) setupDrawDirtyRegionsDisabled(); - if (!ignoreScale) { - setupDrawModelView(left, top, right, bottom, ignoreTransform); - } else { - setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform); - } + setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform); setupDrawTexture(texture); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(); @@ -3492,7 +3564,8 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount, - bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) { + bool swapSrcDst, bool ignoreTransform, GLuint vbo, + ModelViewMode modelViewMode, bool dirty) { setupDraw(); setupDrawWithTexture(); @@ -3501,11 +3574,7 @@ void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, setupDrawBlending(blend, mode, swapSrcDst); setupDrawProgram(); if (!dirty) setupDrawDirtyRegionsDisabled(); - if (!ignoreScale) { - setupDrawModelView(left, top, right, bottom, ignoreTransform); - } else { - setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform); - } + setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform); setupDrawTexture(texture); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(); @@ -3517,7 +3586,7 @@ void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom, GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode, GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount, - bool ignoreTransform, bool ignoreScale, bool dirty) { + bool ignoreTransform, ModelViewMode modelViewMode, bool dirty) { setupDraw(); setupDrawWithTexture(true); @@ -3529,15 +3598,11 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f setupDrawBlending(true, mode); setupDrawProgram(); if (!dirty) setupDrawDirtyRegionsDisabled(); - if (!ignoreScale) { - setupDrawModelView(left, top, right, bottom, ignoreTransform); - } else { - setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform); - } + setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform); setupDrawTexture(texture); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(); - setupDrawShaderUniforms(); + setupDrawShaderUniforms(ignoreTransform); setupDrawMesh(vertices, texCoords); glDrawArrays(drawMode, 0, elementsCount); |
