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

Commit 54be1cdf authored by Romain Guy's avatar Romain Guy
Browse files

Batch glCopyTexImage() calls to get about 15 fps back on SGX.

Change-Id: I04079e070739c1e46df3e90fc388c335e2a7d2b9
parent 40b62576
Loading
Loading
Loading
Loading
+57 −9
Original line number Diff line number Diff line
@@ -476,13 +476,8 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
                        snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
            }

            // Clear the framebuffer where the layer will draw
            glScissor(bounds.left, mSnapshot->height - bounds.bottom,
                    bounds.getWidth(), bounds.getHeight());
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            dirtyClip();
            // Enqueue the buffer coordinates to clear the corresponding region later
            mLayers.push(new Rect(bounds));
        }
    }

@@ -817,6 +812,58 @@ void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
#endif
}

void OpenGLRenderer::clearLayerRegions() {
    const size_t count = mLayers.size();
    if (count == 0) return;

    if (!mSnapshot->isIgnored()) {
        // Doing several glScissor/glClear here can negatively impact
        // GPUs with a tiler architecture, instead we draw quads with
        // the Clear blending mode

        // The list contains bounds that have already been clipped
        // against their initial clip rect, and the current clip
        // is likely different so we need to disable clipping here
        glDisable(GL_SCISSOR_TEST);

        Vertex mesh[count * 6];
        Vertex* vertex = mesh;

        for (uint32_t i = 0; i < count; i++) {
            Rect* bounds = mLayers.itemAt(i);

            Vertex::set(vertex++, bounds->left, bounds->bottom);
            Vertex::set(vertex++, bounds->left, bounds->top);
            Vertex::set(vertex++, bounds->right, bounds->top);
            Vertex::set(vertex++, bounds->left, bounds->bottom);
            Vertex::set(vertex++, bounds->right, bounds->top);
            Vertex::set(vertex++, bounds->right, bounds->bottom);

            delete bounds;
        }

        setupDraw(false);
        setupDrawColor(0.0f, 0.0f, 0.0f, 1.0f);
        setupDrawBlending(true, SkXfermode::kClear_Mode);
        setupDrawProgram();
        setupDrawPureColorUniforms();
        setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true);

        mCaches.unbindMeshBuffer();
        glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
                gVertexStride, &mesh[0].position[0]);
        glDrawArrays(GL_TRIANGLES, 0, count * 6);

        glEnable(GL_SCISSOR_TEST);
    } else {
        for (uint32_t i = 0; i < count; i++) {
            delete mLayers.itemAt(i);
        }
    }

    mLayers.clear();
}

///////////////////////////////////////////////////////////////////////////////
// Transforms
///////////////////////////////////////////////////////////////////////////////
@@ -901,7 +948,8 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom,
// Drawing commands
///////////////////////////////////////////////////////////////////////////////

void OpenGLRenderer::setupDraw() {
void OpenGLRenderer::setupDraw(bool clear) {
    if (clear) clearLayerRegions();
    if (mDirtyClip) {
        setScissorFromClip();
    }
@@ -994,7 +1042,7 @@ void OpenGLRenderer::accountForClear(SkXfermode::Mode mode) {
    if (mColorSet && mode == SkXfermode::kClear_Mode) {
        mColorA = 1.0f;
        mColorR = mColorG = mColorB = 0.0f;
        mSetShaderColor = mDescription.setAlpha8Color(mColorR, mColorG, mColorB, mColorA);
        mSetShaderColor = mDescription.modulate = true;
    }
}

+67 −1
Original line number Diff line number Diff line
@@ -249,6 +249,18 @@ private:
     */
    void composeLayerRect(Layer* layer, const Rect& rect, bool swap = false);

    /**
     * Clears all the regions corresponding to the current list of layers.
     * This method MUST be invoked before any drawing operation.
     */
    void clearLayerRegions();

    /**
     * Renders the specified layer as a textured quad.
     *
     * @param layer The layer to render
     * @param rect The bounds of the layer
     */
    void drawTextureLayer(Layer* layer, const Rect& rect);

    /**
@@ -280,11 +292,53 @@ private:
    void drawColorRect(float left, float top, float right, float bottom,
            int color, SkXfermode::Mode mode, bool ignoreTransform = false);

    /**
     * Draws the shape represented by the specified path texture.
     * This method invokes drawPathTexture() but takes into account
     * the extra left/top offset and the texture offset to correctly
     * position the final shape.
     *
     * @param left The left coordinate of the shape to render
     * @param top The top coordinate of the shape to render
     * @param texture The texture reprsenting the shape
     * @param paint The paint to draw the shape with
     */
    void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);

    /**
     * Renders the rect defined by the specified bounds as a shape.
     * This will render the rect using a path texture, which is used to render
     * rects with stroke effects.
     *
     * @param left The left coordinate of the rect to draw
     * @param top The top coordinate of the rect to draw
     * @param right The right coordinate of the rect to draw
     * @param bottom The bottom coordinate of the rect to draw
     * @param p The paint to draw the rect with
     */
    void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);

    /**
     * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
     * different compositing rules.
     *
     * @param texture The texture to draw with
     * @param left The x coordinate of the bitmap
     * @param top The y coordinate of the bitmap
     * @param paint The paint to render with
     */
    void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);

    /**
     * Renders the rect defined by the specified bounds as an anti-aliased rect.
     *
     * @param left The left coordinate of the rect to draw
     * @param top The top coordinate of the rect to draw
     * @param right The right coordinate of the rect to draw
     * @param bottom The bottom coordinate of the rect to draw
     * @param color The color of the rect
     * @param mode The blending mode to draw the rect
     */
    void drawAARect(float left, float top, float right, float bottom,
            int color, SkXfermode::Mode mode);

@@ -359,6 +413,15 @@ private:
    void drawTextDecorations(const char* text, int bytesCount, float length,
            float x, float y, SkPaint* paint);

    /**
     * Draws a path texture. Path textures are alpha8 bitmaps that need special
     * compositing to apply colors/filters/etc.
     *
     * @param texture The texture to render
     * @param x The x coordinate where the texture will be drawn
     * @param y The y coordinate where the texture will be drawn
     * @param paint The paint to draw the texture with
     */
    void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);

    /**
@@ -434,7 +497,7 @@ private:
    /**
     * Invoked before any drawing operation. This sets required state.
     */
    void setupDraw();
    void setupDraw(bool clear = true);
    /**
     * Various methods to setup OpenGL rendering.
     */
@@ -522,6 +585,9 @@ private:
    // Various caches
    Caches& mCaches;

    // List of rectagnles to clear after saveLayer() is invoked
    Vector<Rect*> mLayers;

    // Indentity matrix
    const mat4 mIdentity;

+3 −1
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
@@ -79,6 +78,9 @@ public class ClearActivity extends Activity {
                }
                canvas.restore();
                canvas.drawText("OpenGLRenderer", 50.0f, 50.0f, mClearPaint);
                mClearPaint.setColor(0xff000000);
                canvas.drawRect(800.0f, 100.0f, 900.0f, 200.0f, mClearPaint);
                mClearPaint.setColor(0x0000ff00);
            }
            canvas.restore();
        }