Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec0cdd1e authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Clean up modelView matrix logic"

parents 7ae9ea57 4063a0e0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -76,7 +76,8 @@ status_t TextSetupFunctor::operator ()(int what, void* data) {
    renderer->setupDrawShader();
    renderer->setupDrawBlending(true, mode);
    renderer->setupDrawProgram();
    renderer->setupDrawModelView(x, y, x, y, pureTranslate, true);
    renderer->setupDrawModelView(kModelViewMode_Translate, false,
            0.0f, 0.0f, 0.0f, 0.0f, pureTranslate);
    // Calling setupDrawTexture with the name 0 will enable the
    // uv attributes and increase the texture unit count
    // texture binding will be performed by the font renderer as
+65 −83
Original line number Diff line number Diff line
@@ -1120,10 +1120,12 @@ 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].x, &mMeshVertices[0].u);
@@ -1235,10 +1237,12 @@ 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].x, &mesh[0].u);

@@ -1349,7 +1353,7 @@ 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);
@@ -1401,9 +1405,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 {
@@ -1868,39 +1873,20 @@ void OpenGLRenderer::setupDrawDirtyRegionsDisabled() {
    mTrackDirtyRegions = false;
}

void OpenGLRenderer::setupDrawModelViewTranslate(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) {
void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset,
        float left, float top, float right, float bottom, bool ignoreTransform) {
    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);
    }
}

@@ -1919,20 +1905,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);
@@ -2121,12 +2106,14 @@ status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry,
        drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
                texture->id, paint != NULL, color, alpha, mode,
                &vertices[0].x, &vertices[0].u,
                GL_TRIANGLES, bitmapCount * 6, true, true, false);
                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].x, &vertices[0].u,
                GL_TRIANGLES, bitmapCount * 6, false, true, 0, true, false);
                GL_TRIANGLES, bitmapCount * 6, false, true, 0,
                kModelViewMode_Translate, false);
    }

    return DrawGlInfo::kStatusDrew;
@@ -2303,7 +2290,7 @@ 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();
@@ -2464,22 +2451,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 {
            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, false,
                    mCaches.patchCache.getMeshBuffer(), true, !mesh->hasEmptyQuads);
        }
                GL_TRIANGLES, mesh->indexCount, false, ignoreTransform,
                mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads);
    }

    return DrawGlInfo::kStatusDrew;
@@ -2506,13 +2492,15 @@ status_t OpenGLRenderer::drawPatches(SkBitmap* bitmap, AssetAtlas::Entry* entry,

    drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f,
            mode, texture->blend, &vertices[0].x, &vertices[0].u,
            GL_TRIANGLES, indexCount, false, true, 0, true, false);
            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;
@@ -2530,10 +2518,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();
@@ -2830,7 +2818,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();
@@ -3111,11 +3100,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());
            }

@@ -3261,7 +3250,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();
@@ -3378,7 +3368,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();
@@ -3387,7 +3378,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;
}
@@ -3406,7 +3397,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();
@@ -3464,7 +3456,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();
@@ -3473,11 +3466,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();
@@ -3489,7 +3478,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();
@@ -3498,11 +3488,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();
@@ -3514,7 +3500,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);
@@ -3526,15 +3512,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);
+56 −12
Original line number Diff line number Diff line
@@ -98,6 +98,24 @@ enum ClipSideFlags {
    kClipSide_ConservativeFull = 0x1F
};

/**
 * Defines additional transformation that should be applied by the model view matrix, beyond that of
 * the currentTransform()
 */
enum ModelViewMode {
    /**
     * Used when the model view should simply translate geometry passed to the shader. The resulting
     * matrix will be a simple translation.
     */
    kModelViewMode_Translate = 0,

    /**
     * Used when the model view should translate and scale geometry. The resulting matrix will be a
     * translation + scale. This is frequently used together with VBO 0, the (0,0,1,1) rect.
     */
    kModelViewMode_TranslateAndScale = 1,
};

///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
@@ -829,32 +847,33 @@ private:
     * @param swapSrcDst Whether or not the src and dst blending operations should be swapped
     * @param ignoreTransform True if the current transform should be ignored
     * @param vbo The VBO used to draw the mesh
     * @param ignoreScale True if the model view matrix should not be scaled
     * @param modelViewMode Defines whether the model view matrix should be scaled
     * @param dirty True if calling this method should dirty the current layer
     */
    void 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 = false, bool ignoreTransform = false, GLuint vbo = 0,
            bool ignoreScale = false, bool dirty = true);
            ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);

    void 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 = false, bool ignoreTransform = false, GLuint vbo = 0,
            bool ignoreScale = false, bool dirty = true);
            ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);

    void 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 = false, bool dirty = true);
            bool ignoreTransform, ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale,
            bool dirty = true);

    /**
     * Draws the specified list of vertices as quads using indexed GL_TRIANGLES.
     * If the number of vertices to draw exceeds the number of indices we have
     * pre-allocated, this method will generate several glDrawElements() calls.
     */
    void drawIndexedQuads(Vertex* mesh, GLsizei quadsCount);
    void issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount);

    /**
     * Draws text underline and strike-through if needed.
@@ -975,14 +994,26 @@ private:
            bool swapSrcDst = false);
    void setupDrawProgram();
    void setupDrawDirtyRegionsDisabled();
    void setupDrawModelViewIdentity(bool offset = false);
    void setupDrawModelView(float left, float top, float right, float bottom,
            bool ignoreTransform = false, bool ignoreModelView = false);
    void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
            bool ignoreTransform = false);

    /**
     * Setup the current program matrices based upon the nature of the geometry.
     *
     * @param mode If kModelViewMode_Translate, the geometry must be translated by the left and top
     * parameters. If kModelViewMode_TranslateAndScale, the geometry that exists in the (0,0, 1,1)
     * space must be scaled up and translated to fill the quad provided in (l,t,r,b). These
     * transformations are stored in the modelView matrix and uploaded to the shader.
     *
     * @param offset Set to true if the the matrix should be fudged (translated) slightly to disambiguate
     * geometry pixel positioning. See Vertex::gGeometryFudgeFactor.
     *
     * @param ignoreTransform Set to true if l,t,r,b coordinates already in layer space,
     * currentTransform() will be ignored. (e.g. when drawing clip in layer coordinates to stencil,
     * or when simple translation has been extracted)
     */
    void setupDrawModelView(ModelViewMode mode, bool offset,
            float left, float top, float right, float bottom, bool ignoreTransform = false);
    void setupDrawColorUniforms();
    void setupDrawPureColorUniforms();
    void setupDrawShaderIdentityUniforms();
    void setupDrawShaderUniforms(bool ignoreTransform = false);
    void setupDrawColorFilterUniforms();
    void setupDrawSimpleMesh();
@@ -1054,7 +1085,20 @@ private:
    // Matrix used for ortho projection in shaders
    mat4 mOrthoMatrix;

    // Model-view matrix used to position/size objects
    /**
     * Model-view matrix used to position/size objects
     *
     * Stores operation-local modifications to the draw matrix that aren't incorporated into the
     * currentTransform().
     *
     * If generated with kModelViewMode_Translate, the mModelView will reflect an x/y offset,
     * e.g. the offset in drawLayer(). If generated with kModelViewMode_TranslateAndScale,
     * mModelView will reflect a translation and scale, e.g. the translation and scale required to
     * make VBO 0 (a rect of (0,0,1,1)) scaled to match the x,y offset, and width/height of a
     * bitmap.
     *
     * Used as input to SkiaShader transformation.
     */
    mat4 mModelView;

    // Number of saved states