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

Commit e2fe78c0 authored by Derek Sollenberger's avatar Derek Sollenberger
Browse files

Cleanup Skia RE display and layer colorTransforms

In the general case we don't set the display's colorMatrix on the paint
if we know it is the identity matrix.  We also now abort early if
the layer has no alpha and no colortransform or colorspace conversion
will change that.

The layer's colortransform is now respected regardless of whether or
not color management is enabled for the RE instance

Also includes some small code refactors to avoid computing the same
values in multiple places.

Test: librenderengine_test
Bug: 180712498
Bug: 181028875
Change-Id: I6e236efc5987d00cb464e8798c48f2b3b21635c5
parent 4c331c85
Loading
Loading
Loading
Loading
+45 −36
Original line number Original line Diff line number Diff line
@@ -454,11 +454,6 @@ static bool needsToneMapping(ui::Dataspace sourceDataspace, ui::Dataspace destin
            sourceTransfer != destTransfer;
            sourceTransfer != destTransfer;
}
}


static bool needsLinearEffect(const mat4& colorTransform, ui::Dataspace sourceDataspace,
                              ui::Dataspace destinationDataspace) {
    return colorTransform != mat4() || needsToneMapping(sourceDataspace, destinationDataspace);
}

void SkiaGLRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
void SkiaGLRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
    // Only run this if RE is running on its own thread. This way the access to GL
    // Only run this if RE is running on its own thread. This way the access to GL
    // operations is guaranteed to be happening on the same thread.
    // operations is guaranteed to be happening on the same thread.
@@ -491,14 +486,19 @@ void SkiaGLRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> shader,
sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> shader,
                                                              const LayerSettings* layer,
                                                              const LayerSettings* layer,
                                                              const DisplaySettings& display,
                                                              const DisplaySettings& display,
                                                              bool undoPremultipliedAlpha) {
                                                              bool undoPremultipliedAlpha,
                                                              bool requiresLinearEffect) {
    if (layer->stretchEffect.hasEffect()) {
    if (layer->stretchEffect.hasEffect()) {
        // TODO: Implement
        // TODO: Implement
    }
    }
    if (mUseColorManagement &&
    if (requiresLinearEffect) {
        needsLinearEffect(layer->colorTransform, layer->sourceDataspace, display.outputDataspace)) {
        const ui::Dataspace inputDataspace =
        LinearEffect effect = LinearEffect{.inputDataspace = layer->sourceDataspace,
                mUseColorManagement ? layer->sourceDataspace : ui::Dataspace::UNKNOWN;
                                           .outputDataspace = display.outputDataspace,
        const ui::Dataspace outputDataspace =
                mUseColorManagement ? display.outputDataspace : ui::Dataspace::UNKNOWN;

        LinearEffect effect = LinearEffect{.inputDataspace = inputDataspace,
                                           .outputDataspace = outputDataspace,
                                           .undoPremultipliedAlpha = undoPremultipliedAlpha};
                                           .undoPremultipliedAlpha = undoPremultipliedAlpha};


        auto effectIter = mRuntimeEffects.find(effect);
        auto effectIter = mRuntimeEffects.find(effect);
@@ -630,11 +630,10 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
        }
        }
    }
    }


    const ui::Dataspace dstDataspace =
            mUseColorManagement ? display.outputDataspace : ui::Dataspace::UNKNOWN;
    sk_sp<SkSurface> dstSurface =
    sk_sp<SkSurface> dstSurface =
            surfaceTextureRef->getTexture()->getOrCreateSurface(mUseColorManagement
            surfaceTextureRef->getTexture()->getOrCreateSurface(dstDataspace, grContext.get());
                                                                        ? display.outputDataspace
                                                                        : ui::Dataspace::UNKNOWN,
                                                                grContext.get());


    SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
    SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
    if (dstCanvas == nullptr) {
    if (dstCanvas == nullptr) {
@@ -691,13 +690,18 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
        SkPaint paint;
        SkPaint paint;
        sk_sp<SkShader> shader =
        sk_sp<SkShader> shader =
                SkShaders::Color(SkColor4f{.fR = 0., .fG = 0., .fB = 0., .fA = 1.0},
                SkShaders::Color(SkColor4f{.fR = 0., .fG = 0., .fB = 0., .fA = 1.0},
                                 toSkColorSpace(mUseColorManagement ? display.outputDataspace
                                 toSkColorSpace(dstDataspace));
                                                                    : ui::Dataspace::UNKNOWN));
        paint.setShader(shader);
        paint.setShader(shader);
        clearRegion.setRects(skRects, numRects);
        clearRegion.setRects(skRects, numRects);
        canvas->drawRegion(clearRegion, paint);
        canvas->drawRegion(clearRegion, paint);
    }
    }


    // setup color filter if necessary
    sk_sp<SkColorFilter> displayColorTransform;
    if (display.colorTransform != mat4()) {
        displayColorTransform = SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform));
    }

    for (const auto& layer : layers) {
    for (const auto& layer : layers) {
        ATRACE_NAME("DrawLayer");
        ATRACE_NAME("DrawLayer");


@@ -797,15 +801,22 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
            continue;
            continue;
        }
        }


        const ui::Dataspace targetDataspace = mUseColorManagement
        const bool requiresLinearEffect = layer->colorTransform != mat4() ||
                ? (needsLinearEffect(layer->colorTransform, layer->sourceDataspace,
                (mUseColorManagement &&
                                     display.outputDataspace)
                 needsToneMapping(layer->sourceDataspace, display.outputDataspace));
                           // If we need to map to linear space, then mark the source image with the

                           // same colorspace as the destination surface so that Skia's color
        // quick abort from drawing the remaining portion of the layer
        if (layer->alpha == 0 && !requiresLinearEffect &&
            (!displayColorTransform || displayColorTransform->isAlphaUnchanged())) {
            continue;
        }

        // If we need to map to linear space or color management is disabled, then mark the source
        // image with the same colorspace as the destination surface so that Skia's color
        // management is a no-op.
        // management is a no-op.
                           ? display.outputDataspace
        const ui::Dataspace layerDataspace = (!mUseColorManagement || requiresLinearEffect)
                           : layer->sourceDataspace)
                ? dstDataspace
                : ui::Dataspace::UNKNOWN;
                : layer->sourceDataspace;


        SkPaint paint;
        SkPaint paint;
        if (layer->source.buffer.buffer) {
        if (layer->source.buffer.buffer) {
@@ -824,7 +835,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
            }
            }


            sk_sp<SkImage> image =
            sk_sp<SkImage> image =
                    imageTextureRef->getTexture()->makeImage(targetDataspace,
                    imageTextureRef->getTexture()->makeImage(layerDataspace,
                                                             item.usePremultipliedAlpha
                                                             item.usePremultipliedAlpha
                                                                     ? kPremul_SkAlphaType
                                                                     ? kPremul_SkAlphaType
                                                                     : kUnpremul_SkAlphaType,
                                                                     : kUnpremul_SkAlphaType,
@@ -880,12 +891,12 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
            if (item.isOpaque) {
            if (item.isOpaque) {
                shader = SkShaders::Blend(SkBlendMode::kPlus, shader,
                shader = SkShaders::Blend(SkBlendMode::kPlus, shader,
                                          SkShaders::Color(SkColors::kBlack,
                                          SkShaders::Color(SkColors::kBlack,
                                                           toSkColorSpace(targetDataspace)));
                                                           toSkColorSpace(layerDataspace)));
            }
            }


            paint.setShader(
            paint.setShader(createRuntimeEffectShader(shader, layer, display,
                    createRuntimeEffectShader(shader, layer, display,
                                                      !item.isOpaque && item.usePremultipliedAlpha,
                                              !item.isOpaque && item.usePremultipliedAlpha));
                                                      requiresLinearEffect));
            paint.setAlphaf(layer->alpha);
            paint.setAlphaf(layer->alpha);
        } else {
        } else {
            ATRACE_NAME("DrawColor");
            ATRACE_NAME("DrawColor");
@@ -894,15 +905,13 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                                                                .fG = color.g,
                                                                .fG = color.g,
                                                                .fB = color.b,
                                                                .fB = color.b,
                                                                .fA = layer->alpha},
                                                                .fA = layer->alpha},
                                                      toSkColorSpace(targetDataspace));
                                                      toSkColorSpace(layerDataspace));
            paint.setShader(createRuntimeEffectShader(shader, layer, display,
            paint.setShader(createRuntimeEffectShader(shader, layer, display,
                                                      /* undoPremultipliedAlpha */ false));
                                                      /* undoPremultipliedAlpha */ false,
                                                      requiresLinearEffect));
        }
        }


        sk_sp<SkColorFilter> filter =
        paint.setColorFilter(displayColorTransform);
                SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform));

        paint.setColorFilter(filter);


        if (layer->geometry.roundedCornersRadius > 0) {
        if (layer->geometry.roundedCornersRadius > 0) {
            paint.setAntiAlias(true);
            paint.setAntiAlias(true);
+4 −3
Original line number Original line Diff line number Diff line
@@ -92,11 +92,12 @@ private:
    void initCanvas(SkCanvas* canvas, const DisplaySettings& display);
    void initCanvas(SkCanvas* canvas, const DisplaySettings& display);
    void drawShadow(SkCanvas* canvas, const SkRect& casterRect, float casterCornerRadius,
    void drawShadow(SkCanvas* canvas, const SkRect& casterRect, float casterCornerRadius,
                    const ShadowSettings& shadowSettings);
                    const ShadowSettings& shadowSettings);
    // If mUseColorManagement is correct and layer needsLinearEffect, it returns a linear runtime
    // If requiresLinearEffect is true or the layer has a stretchEffect a new shader is returned.
    // shader. Otherwise it returns the input shader.
    // Otherwise it returns the input shader.
    sk_sp<SkShader> createRuntimeEffectShader(sk_sp<SkShader> shader, const LayerSettings* layer,
    sk_sp<SkShader> createRuntimeEffectShader(sk_sp<SkShader> shader, const LayerSettings* layer,
                                              const DisplaySettings& display,
                                              const DisplaySettings& display,
                                              bool undoPremultipliedAlpha);
                                              bool undoPremultipliedAlpha,
                                              bool requiresLinearEffect);


    EGLDisplay mEGLDisplay;
    EGLDisplay mEGLDisplay;
    EGLContext mEGLContext;
    EGLContext mEGLContext;