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

Commit acb42c01 authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "Use colorFilters when rendering to an sRGB bitmap."

parents 84e328c9 b851b197
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ Canvas* Picture::beginRecording(int width, int height) {
    mWidth = width;
    mHeight = height;
    SkCanvas* canvas = mRecorder->beginRecording(SkIntToScalar(width), SkIntToScalar(height));
    return Canvas::create_canvas(canvas, Canvas::XformToSRGB::kDefer);
    return Canvas::create_canvas(canvas);
}

void Picture::endRecording() {
+2 −6
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@

#include "CreateJavaOutputStreamAdaptor.h"

#include "SkColorSpaceXformCanvas.h"
#include "SkDocument.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
@@ -95,10 +94,7 @@ public:

            SkCanvas* canvas = document->beginPage(page->mWidth, page->mHeight,
                    &(page->mContentRect));
            std::unique_ptr<SkCanvas> toSRGBCanvas =
                    SkCreateColorSpaceXformCanvas(canvas, SkColorSpace::MakeSRGB());

            toSRGBCanvas->drawPicture(page->mPicture);
            canvas->drawPicture(page->mPicture);

            document->endPage();
        }
@@ -131,7 +127,7 @@ static jlong nativeStartPage(JNIEnv* env, jobject thiz, jlong documentPtr,
    PdfDocument* document = reinterpret_cast<PdfDocument*>(documentPtr);
    SkCanvas* canvas = document->startPage(pageWidth, pageHeight,
            contentLeft, contentTop, contentRight, contentBottom);
    return reinterpret_cast<jlong>(Canvas::create_canvas(canvas, Canvas::XformToSRGB::kDefer));
    return reinterpret_cast<jlong>(Canvas::create_canvas(canvas));
}

static void nativeFinishPage(JNIEnv* env, jobject thiz, jlong documentPtr) {
+37 −18
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@

#include <SkCanvasStateUtils.h>
#include <SkColorFilter.h>
// TODO remove me!
#include <SkColorSpaceXformCanvas.h>
#include <SkDrawable.h>
#include <SkDeque.h>
@@ -48,26 +47,29 @@ Canvas* Canvas::create_canvas(const SkBitmap& bitmap) {
    return new SkiaCanvas(bitmap);
}

Canvas* Canvas::create_canvas(SkCanvas* skiaCanvas, XformToSRGB xformToSRGB) {
    return new SkiaCanvas(skiaCanvas, xformToSRGB);
Canvas* Canvas::create_canvas(SkCanvas* skiaCanvas) {
    return new SkiaCanvas(skiaCanvas);
}

SkiaCanvas::SkiaCanvas() {}

SkiaCanvas::SkiaCanvas(SkCanvas* canvas, XformToSRGB xformToSRGB)
    : mCanvas(canvas)
{
    LOG_ALWAYS_FATAL_IF(XformToSRGB::kImmediate == xformToSRGB);
}
SkiaCanvas::SkiaCanvas(SkCanvas* canvas) : mCanvas(canvas) {}

SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
    sk_sp<SkColorSpace> cs = bitmap.refColorSpace();
    mCanvasOwned =
            std::unique_ptr<SkCanvas>(new SkCanvas(bitmap, SkCanvas::ColorBehavior::kLegacy));
    mCanvasWrapper = SkCreateColorSpaceXformCanvas(mCanvasOwned.get(),
            cs == nullptr ? SkColorSpace::MakeSRGB() : std::move(cs));
    if (cs.get() == nullptr || cs->isSRGB()) {
        mCanvas = mCanvasOwned.get();
    } else {
        /** The wrapper is needed if we are drawing into a non-sRGB destination, since
         *  we need to transform all colors (not just bitmaps via filters) into the
         *  destination's colorspace.
         */
        mCanvasWrapper = SkCreateColorSpaceXformCanvas(mCanvasOwned.get(), std::move(cs));
        mCanvas = mCanvasWrapper.get();
    }
}

SkiaCanvas::~SkiaCanvas() {}

@@ -75,6 +77,7 @@ void SkiaCanvas::reset(SkCanvas* skiaCanvas) {
    if (mCanvas != skiaCanvas) {
        mCanvas = skiaCanvas;
        mCanvasOwned.reset();
        mCanvasWrapper.reset();
    }
    mSaveStack.reset(nullptr);
    mHighContrastText = false;
@@ -88,13 +91,15 @@ void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
    sk_sp<SkColorSpace> cs = bitmap.refColorSpace();
    std::unique_ptr<SkCanvas> newCanvas =
            std::unique_ptr<SkCanvas>(new SkCanvas(bitmap, SkCanvas::ColorBehavior::kLegacy));
    std::unique_ptr<SkCanvas> newCanvasWrapper = SkCreateColorSpaceXformCanvas(newCanvas.get(),
            cs == nullptr ? SkColorSpace::MakeSRGB() : std::move(cs));
    std::unique_ptr<SkCanvas> newCanvasWrapper;
    if (cs.get() != nullptr && !cs->isSRGB()) {
        newCanvasWrapper = SkCreateColorSpaceXformCanvas(newCanvas.get(), std::move(cs));
    }

    // deletes the previously owned canvas (if any)
    mCanvasOwned = std::move(newCanvas);
    mCanvasWrapper = std::move(newCanvasWrapper);
    mCanvas = mCanvasWrapper.get();
    mCanvas = mCanvasWrapper ? mCanvasWrapper.get() : mCanvasOwned.get();

    // clean up the old save stack
    mSaveStack.reset(nullptr);
@@ -531,13 +536,27 @@ void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, cons
// Canvas draw operations: Bitmaps
// ----------------------------------------------------------------------------

inline static const SkPaint* addFilter(const SkPaint* origPaint, SkPaint* tmpPaint,
        sk_sp<SkColorFilter> colorFilter) {
    if (colorFilter) {
const SkPaint* SkiaCanvas::addFilter(const SkPaint* origPaint, SkPaint* tmpPaint,
        sk_sp<SkColorFilter> colorSpaceFilter) {
    /* We don't apply the colorSpace filter if this canvas is already wrapped with
     * a SkColorSpaceXformCanvas since it already takes care of converting the
     * contents of the bitmap into the appropriate colorspace.  The mCanvasWrapper
     * should only be used if this canvas is backed by a surface/bitmap that is known
     * to have a non-sRGB colorspace.
     */
    if (!mCanvasWrapper && colorSpaceFilter) {
        if (origPaint) {
            *tmpPaint = *origPaint;
        }
        tmpPaint->setColorFilter(colorFilter);

        if (tmpPaint->getColorFilter()) {
            tmpPaint->setColorFilter(SkColorFilter::MakeComposeFilter(
                    tmpPaint->refColorFilter(), colorSpaceFilter));
            LOG_ALWAYS_FATAL_IF(!tmpPaint->getColorFilter());
        } else {
            tmpPaint->setColorFilter(colorSpaceFilter);
        }

        return tmpPaint;
    } else {
        return origPaint;
+4 −5
Original line number Diff line number Diff line
@@ -37,12 +37,8 @@ public:
     *  @param canvas SkCanvas to handle calls made to this SkiaCanvas. Must
     *      not be NULL. This constructor does not take ownership, so the caller
     *      must guarantee that it remains valid while the SkiaCanvas is valid.
     *  @param xformToSRGB Indicates if bitmaps should be xformed to the sRGB
     *      color space before drawing.  This makes sense for software rendering.
     *      For the picture case, it may make more sense to leave bitmaps as is,
     *      and handle the xform when replaying the picture.
     */
    explicit SkiaCanvas(SkCanvas* canvas, XformToSRGB xformToSRGB);
    explicit SkiaCanvas(SkCanvas* canvas);

    virtual ~SkiaCanvas();

@@ -182,6 +178,9 @@ private:
    void drawPoints(const float* points, int count, const SkPaint& paint,
            SkCanvas::PointMode mode);

    const SkPaint* addFilter(const SkPaint* origPaint, SkPaint* tmpPaint,
            sk_sp<SkColorFilter> colorSpaceFilter);

    class Clip;

    std::unique_ptr<SkCanvas> mCanvasWrapper; // might own a wrapper on the canvas
+1 −12
Original line number Diff line number Diff line
@@ -98,15 +98,6 @@ public:
    static WARN_UNUSED_RESULT Canvas* create_recording_canvas(int width, int height,
            uirenderer::RenderNode* renderNode = nullptr);

    enum class XformToSRGB {
        // Transform any Bitmaps to the sRGB color space before drawing.
        kImmediate,

        // Draw the Bitmap as is.  This likely means that we are recording and that the
        // transform can be handled at playback time.
        kDefer,
    };

    /**
     *  Create a new Canvas object which delegates to an SkCanvas.
     *
@@ -114,12 +105,10 @@ public:
     *      delegated to this object. This function will call ref() on the
     *      SkCanvas, and the returned Canvas will unref() it upon
     *      destruction.
     *  @param xformToSRGB Indicates if bitmaps should be xformed to the sRGB
     *      color space before drawing.
     *  @return new non-null Canvas Object.  The type of DisplayList produced by this canvas is
     *      determined based on  Properties::getRenderPipelineType().
     */
    static Canvas* create_canvas(SkCanvas* skiaCanvas, XformToSRGB xformToSRGB);
    static Canvas* create_canvas(SkCanvas* skiaCanvas);

    /**
     *  Provides a Skia SkCanvas interface that acts as a proxy to this Canvas.
Loading