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

Commit 7230a74e authored by Romain Guy's avatar Romain Guy
Browse files

Composite layers as regions.

This change detects what area of a layer was drawn into and generates a mesh
to match this area exactly. This can be used to avoid blending empty pixels
when the layer is composited.
This change also adds proper layers support to lines rendering and implements
layers composition in a more readable way.

Change-Id: I4a5588b98b19bd66891ebdc39631b193c5e31999
parent a07105b7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -53,6 +53,10 @@ Caches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO),

    mDebugLevel = readDebugLevel();
    LOGD("Enabling debug mode %d", mDebugLevel);

#if RENDER_LAYERS_AS_REGIONS
    LOGD("Layers will be composited as regions");
#endif
}

Caches::~Caches() {
+54 −50
Original line number Diff line number Diff line
@@ -604,43 +604,23 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
        size_t count;
        const android::Rect* rects = layer->region.getArray(&count);

        setupDraw();

        ProgramDescription description;
        description.hasTexture = true;

        const float alpha = layer->alpha / 255.0f;
        const bool setColor = description.setColor(alpha, alpha, alpha, alpha);
        chooseBlending(layer->blend || layer->alpha < 255, layer->mode, description, false);

        useProgram(mCaches.programCache.get(description));

        // Texture
        bindTexture(layer->texture);
        glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0);

        // Always premultiplied
        if (setColor) {
            mCaches.currentProgram->setColor(alpha, alpha, alpha, alpha);
        }

        // Mesh
        int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
        glEnableVertexAttribArray(texCoordsSlot);

        mModelView.loadIdentity();
        mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);

        const float texX = 1.0f / float(layer->width);
        const float texY = 1.0f / float(layer->height);

        TextureVertex* mesh = mCaches.getRegionMesh();
        GLsizei numQuads = 0;

        glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
                gMeshStride, &mesh[0].position[0]);
        glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
                gMeshStride, &mesh[0].texture[0]);
        setupDraw();
        setupDrawWithTexture();
        setupDrawColor(alpha, alpha, alpha, alpha);
        setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
        setupDrawProgram();
        setupDrawDirtyRegionsDisabled();
        setupDrawPureColorUniforms();
        setupDrawTexture(layer->texture);
        setupDrawModelViewIdentity();
        setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0]);

        for (size_t i = 0; i < count; i++) {
            const android::Rect* r = &rects[i];
@@ -670,7 +650,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
        }

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glDisableVertexAttribArray(texCoordsSlot);
        finishDrawTexture();

#if DEBUG_LAYERS_AS_REGIONS
        uint32_t colors[] = {
@@ -1186,7 +1166,6 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
}

void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
    // TODO: Should do quickReject for each line
    if (mSnapshot->isIgnored()) return;

    const bool isAA = paint->isAntiAlias();
@@ -1200,6 +1179,7 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
    getAlphaAndMode(paint, &alpha, &mode);

    int verticesCount = count >> 2;
    int generatedVerticesCount = 0;
    if (!isHairLine) {
        // TODO: AA needs more vertices
        verticesCount *= 6;
@@ -1246,6 +1226,12 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
            vec2 p3 = b + n;
            vec2 p4 = b - n;

            const float left = fmin(p1.x, fmin(p2.x, fmin(p3.x, p4.x)));
            const float right = fmax(p1.x, fmax(p2.x, fmax(p3.x, p4.x)));
            const float top = fmin(p1.y, fmin(p2.y, fmin(p3.y, p4.y)));
            const float bottom = fmax(p1.y, fmax(p2.y, fmax(p3.y, p4.y)));

            if (!quickReject(left, top, right, bottom)) {
                // Draw the line as 2 triangles, could be optimized
                // by using only 4 vertices and the correct indices
                // Also we should probably used non textured vertices
@@ -1257,20 +1243,38 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
                TextureVertex::set(vertex++, p3.x, p3.y, 0.0f, 0.0f);
                TextureVertex::set(vertex++, p4.x, p4.y, 0.0f, 0.0f);

            // TODO: Mark the dirty regions when RENDER_LAYERS_AS_REGIONS is set
                generatedVerticesCount += 6;

                dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
            }
        }

        if (generatedVerticesCount > 0) {
            // GL_LINE does not give the result we want to match Skia
        glDrawArrays(GL_TRIANGLES, 0, verticesCount);
            glDrawArrays(GL_TRIANGLES, 0, generatedVerticesCount);
        }
    } else {
        // TODO: Handle the AA case
        for (int i = 0; i < count; i += 4) {
            const float left = fmin(points[i], points[i + 1]);
            const float right = fmax(points[i], points[i + 1]);
            const float top = fmin(points[i + 2], points[i + 3]);
            const float bottom = fmax(points[i + 2], points[i + 3]);

            if (!quickReject(left, top, right, bottom)) {
                TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
                TextureVertex::set(vertex++, points[i + 2], points[i + 3], 0.0f, 0.0f);

                generatedVerticesCount += 2;

                dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
            }
        }

        if (generatedVerticesCount > 0) {
            glLineWidth(1.0f);
        glDrawArrays(GL_LINES, 0, verticesCount);
            glDrawArrays(GL_LINES, 0, generatedVerticesCount);
        }
    }
}

+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
 */

// If turned on, layers drawn inside FBOs are optimized with regions
#define RENDER_LAYERS_AS_REGIONS 0
#define RENDER_LAYERS_AS_REGIONS 1

/**
 * Debug level for app developers.
+3 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.View;

@@ -31,7 +32,9 @@ public class LinesActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setBackgroundDrawable(new ColorDrawable(0xffffffff));
        final LinesView view = new LinesView(this);
        //view.setAlpha(0.80f);
        setContentView(view);
    }

@@ -91,8 +94,6 @@ public class LinesActivity extends Activity {
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            canvas.drawARGB(255, 255, 255, 255);

            canvas.save();
            canvas.translate(100.0f, 20.0f);