summaryrefslogtreecommitdiffstats
path: root/libs/hwui/OpenGLRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
-rw-r--r--libs/hwui/OpenGLRenderer.cpp322
1 files changed, 174 insertions, 148 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 4d76bed..e256ec2 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -779,11 +779,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 +834,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 +909,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 +946,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 +972,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());
@@ -1034,7 +1032,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 +1121,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 +1162,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 +1238,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 +1277,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 +1307,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 +1354,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 +1406,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 {
@@ -1626,8 +1630,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 +1655,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 +1788,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 +1846,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 +1855,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 +1868,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 +1918,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(mOrthoMatrix, 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(mOrthoMatrix, mModelView, mat4::identity(), offset);
+ if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
}
}
@@ -1921,20 +1950,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);
@@ -2122,13 +2150,15 @@ status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry,
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 +2168,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;
}
@@ -2161,7 +2191,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;
}
@@ -2188,7 +2218,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;
}
@@ -2271,7 +2301,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 +2335,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 +2357,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;
}
@@ -2397,12 +2427,12 @@ status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
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 +2447,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 +2460,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 +2496,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 +2536,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 +2563,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 +2609,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 +2636,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 +2656,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 +2694,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 +2719,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 +2741,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 +2763,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 +2800,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 +2865,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 +2964,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 +3038,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 +3109,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 +3147,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 +3161,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 +3172,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 +3282,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 +3297,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 +3313,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)) {
@@ -3369,7 +3403,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 +3415,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 +3425,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 +3444,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 +3466,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 +3503,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 +3513,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 +3525,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 +3535,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 +3547,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 +3559,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);