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

Commit 23403195 authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Draw gainmaps in HDR"

parents 39ef97a5 115195e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -511,6 +511,7 @@ cc_defaults {
        "canvas/CanvasOpBuffer.cpp",
        "canvas/CanvasOpRasterizer.cpp",
        "effects/StretchEffect.cpp",
        "effects/GainmapRenderer.cpp",
        "pipeline/skia/HolePunch.cpp",
        "pipeline/skia/SkiaDisplayList.cpp",
        "pipeline/skia/SkiaRecordingCanvas.cpp",
+80 −53
Original line number Diff line number Diff line
@@ -19,9 +19,9 @@
#include <GrRecordingContext.h>
#include <SkMesh.h>
#include <hwui/Paint.h>
#include <log/log.h>

#include <experimental/type_traits>
#include <log/log.h>
#include <utility>

#include "SkAndroidFrameworkUtils.h"
@@ -45,6 +45,7 @@
#include "SkVertices.h"
#include "Tonemapper.h"
#include "VectorDrawable.h"
#include "effects/GainmapRenderer.h"
#include "include/gpu/GpuTypes.h"  // from Skia
#include "include/gpu/GrDirectContext.h"
#include "pipeline/skia/AnimatedDrawables.h"
@@ -332,9 +333,15 @@ struct DrawPicture final : Op {

struct DrawImage final : Op {
    static const auto kType = Type::DrawImage;
    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y,
              const SkSamplingOptions& sampling, const SkPaint* paint, BitmapPalette palette)
            : image(std::move(image)), x(x), y(y), sampling(sampling), palette(palette) {
    DrawImage(DrawImagePayload&& payload, SkScalar x, SkScalar y, const SkSamplingOptions& sampling,
              const SkPaint* paint)
            : image(std::move(payload.image))
            , x(x)
            , y(y)
            , sampling(sampling)
            , palette(payload.palette)
            , gainmap(std::move(payload.gainmapImage))
            , gainmapInfo(payload.gainmapInfo) {
        if (paint) {
            this->paint = *paint;
        }
@@ -344,19 +351,34 @@ struct DrawImage final : Op {
    SkSamplingOptions sampling;
    SkPaint paint;
    BitmapPalette palette;
    sk_sp<const SkImage> gainmap;
    SkGainmapInfo gainmapInfo;

    void draw(SkCanvas* c, const SkMatrix&) const {
        if (gainmap) {
            SkRect src = SkRect::MakeWH(image->width(), image->height());
            SkRect dst = SkRect::MakeXYWH(x, y, src.width(), src.height());
            DrawGainmapBitmap(c, image, src, dst, sampling, &paint,
                              SkCanvas::kFast_SrcRectConstraint, gainmap, gainmapInfo);
        } else {
            SkPaint newPaint = paint;
            tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
            c->drawImage(image.get(), x, y, sampling, &newPaint);
        }
    }
};
struct DrawImageRect final : Op {
    static const auto kType = Type::DrawImageRect;
    DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
    DrawImageRect(DrawImagePayload&& payload, const SkRect* src, const SkRect& dst,
                  const SkSamplingOptions& sampling, const SkPaint* paint,
                  SkCanvas::SrcRectConstraint constraint, BitmapPalette palette)
            : image(std::move(image)), dst(dst), sampling(sampling), constraint(constraint)
            , palette(palette) {
                  SkCanvas::SrcRectConstraint constraint)
            : image(std::move(payload.image))
            , dst(dst)
            , sampling(sampling)
            , constraint(constraint)
            , palette(payload.palette)
            , gainmap(std::move(payload.gainmapImage))
            , gainmapInfo(payload.gainmapInfo) {
        this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height());
        if (paint) {
            this->paint = *paint;
@@ -368,25 +390,32 @@ struct DrawImageRect final : Op {
    SkPaint paint;
    SkCanvas::SrcRectConstraint constraint;
    BitmapPalette palette;
    sk_sp<const SkImage> gainmap;
    SkGainmapInfo gainmapInfo;

    void draw(SkCanvas* c, const SkMatrix&) const {
        if (gainmap) {
            DrawGainmapBitmap(c, image, src, dst, sampling, &paint, constraint, gainmap,
                              gainmapInfo);
        } else {
            SkPaint newPaint = paint;
            tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
            c->drawImageRect(image.get(), src, dst, sampling, &newPaint, constraint);
        }
    }
};
struct DrawImageLattice final : Op {
    static const auto kType = Type::DrawImageLattice;
    DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src,
                     const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
                     BitmapPalette palette)
            : image(std::move(image))
    DrawImageLattice(DrawImagePayload&& payload, int xs, int ys, int fs, const SkIRect& src,
                     const SkRect& dst, SkFilterMode filter, const SkPaint* paint)
            : image(std::move(payload.image))
            , xs(xs)
            , ys(ys)
            , fs(fs)
            , src(src)
            , dst(dst)
            , filter(filter)
            , palette(palette) {
            , palette(payload.palette) {
        if (paint) {
            this->paint = *paint;
        }
@@ -399,6 +428,8 @@ struct DrawImageLattice final : Op {
    SkPaint paint;
    BitmapPalette palette;
    void draw(SkCanvas* c, const SkMatrix&) const {
        // TODO: Support drawing a gainmap 9-patch?

        auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs * sizeof(int));
        auto colors = (0 == fs) ? nullptr : pod<SkColor>(this, (xs + ys) * sizeof(int));
        auto flags =
@@ -781,27 +812,25 @@ void DisplayListData::drawPicture(const SkPicture* picture, const SkMatrix* matr
                                  const SkPaint* paint) {
    this->push<DrawPicture>(0, picture, matrix, paint);
}
void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
                                const SkSamplingOptions& sampling, const SkPaint* paint,
                                BitmapPalette palette) {
    this->push<DrawImage>(0, std::move(image), x, y, sampling, paint, palette);
void DisplayListData::drawImage(DrawImagePayload&& payload, SkScalar x, SkScalar y,
                                const SkSamplingOptions& sampling, const SkPaint* paint) {
    this->push<DrawImage>(0, std::move(payload), x, y, sampling, paint);
}
void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
void DisplayListData::drawImageRect(DrawImagePayload&& payload, const SkRect* src,
                                    const SkRect& dst, const SkSamplingOptions& sampling,
                                    const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
                                    BitmapPalette palette) {
    this->push<DrawImageRect>(0, std::move(image), src, dst, sampling, paint, constraint, palette);
                                    const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
    this->push<DrawImageRect>(0, std::move(payload), src, dst, sampling, paint, constraint);
}
void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
                                       const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
                                       BitmapPalette palette) {
void DisplayListData::drawImageLattice(DrawImagePayload&& payload, const SkCanvas::Lattice& lattice,
                                       const SkRect& dst, SkFilterMode filter,
                                       const SkPaint* paint) {
    int xs = lattice.fXCount, ys = lattice.fYCount;
    int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0;
    size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) +
                   fs * sizeof(SkColor);
    LOG_FATAL_IF(!lattice.fBounds);
    void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds,
                                             dst, filter, paint, palette);
    void* pod = this->push<DrawImageLattice>(bytes, std::move(payload), xs, ys, fs,
                                             *lattice.fBounds, dst, filter, paint);
    copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes,
           fs);
}
@@ -1108,57 +1137,55 @@ void RecordingCanvas::drawRippleDrawable(const skiapipeline::RippleDrawableParam
    fDL->drawRippleDrawable(params);
}

void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
                                const SkSamplingOptions& sampling, const SkPaint* paint,
                                BitmapPalette palette) {
    fDL->drawImage(image, x, y, sampling, paint, palette);
void RecordingCanvas::drawImage(DrawImagePayload&& payload, SkScalar x, SkScalar y,
                                const SkSamplingOptions& sampling, const SkPaint* paint) {
    fDL->drawImage(std::move(payload), x, y, sampling, paint);
}

void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src,
void RecordingCanvas::drawImageRect(DrawImagePayload&& payload, const SkRect& src,
                                    const SkRect& dst, const SkSamplingOptions& sampling,
                                    const SkPaint* paint, SrcRectConstraint constraint,
                                    BitmapPalette palette) {
    fDL->drawImageRect(image, &src, dst, sampling, paint, constraint, palette);
                                    const SkPaint* paint, SrcRectConstraint constraint) {
    fDL->drawImageRect(std::move(payload), &src, dst, sampling, paint, constraint);
}

void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice,
                                       const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
                                       BitmapPalette palette) {
    if (!image || dst.isEmpty()) {
void RecordingCanvas::drawImageLattice(DrawImagePayload&& payload, const Lattice& lattice,
                                       const SkRect& dst, SkFilterMode filter,
                                       const SkPaint* paint) {
    if (!payload.image || dst.isEmpty()) {
        return;
    }

    SkIRect bounds;
    Lattice latticePlusBounds = lattice;
    if (!latticePlusBounds.fBounds) {
        bounds = SkIRect::MakeWH(image->width(), image->height());
        bounds = SkIRect::MakeWH(payload.image->width(), payload.image->height());
        latticePlusBounds.fBounds = &bounds;
    }

    if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
        fDL->drawImageLattice(image, latticePlusBounds, dst, filter, paint, palette);
    if (SkLatticeIter::Valid(payload.image->width(), payload.image->height(), latticePlusBounds)) {
        fDL->drawImageLattice(std::move(payload), latticePlusBounds, dst, filter, paint);
    } else {
        SkSamplingOptions sampling(filter, SkMipmapMode::kNone);
        fDL->drawImageRect(image, nullptr, dst, sampling, paint, kFast_SrcRectConstraint, palette);
        fDL->drawImageRect(std::move(payload), nullptr, dst, sampling, paint,
                           kFast_SrcRectConstraint);
    }
}

void RecordingCanvas::onDrawImage2(const SkImage* img, SkScalar x, SkScalar y,
                                   const SkSamplingOptions& sampling, const SkPaint* paint) {
    fDL->drawImage(sk_ref_sp(img), x, y, sampling, paint, BitmapPalette::Unknown);
    fDL->drawImage(DrawImagePayload(img), x, y, sampling, paint);
}

void RecordingCanvas::onDrawImageRect2(const SkImage* img, const SkRect& src, const SkRect& dst,
                                       const SkSamplingOptions& sampling, const SkPaint* paint,
                                       SrcRectConstraint constraint) {
    fDL->drawImageRect(sk_ref_sp(img), &src, dst, sampling, paint, constraint,
                       BitmapPalette::Unknown);
    fDL->drawImageRect(DrawImagePayload(img), &src, dst, sampling, paint, constraint);
}

void RecordingCanvas::onDrawImageLattice2(const SkImage* img, const SkCanvas::Lattice& lattice,
                                          const SkRect& dst, SkFilterMode filter,
                                          const SkPaint* paint) {
    fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, filter, paint, BitmapPalette::Unknown);
    fDL->drawImageLattice(DrawImagePayload(img), lattice, dst, filter, paint);
}

void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+47 −20
Original line number Diff line number Diff line
@@ -16,6 +16,14 @@

#pragma once

#include <SkCanvas.h>
#include <SkCanvasVirtualEnforcer.h>
#include <SkDrawable.h>
#include <SkGainmapInfo.h>
#include <SkNoDrawCanvas.h>
#include <SkPaint.h>
#include <SkPath.h>
#include <SkRect.h>
#include <SkRuntimeEffect.h>
#include <log/log.h>

@@ -23,13 +31,7 @@
#include <vector>

#include "CanvasTransform.h"
#include "SkCanvas.h"
#include "SkCanvasVirtualEnforcer.h"
#include "SkDrawable.h"
#include "SkNoDrawCanvas.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRect.h"
#include "Gainmap.h"
#include "hwui/Bitmap.h"
#include "pipeline/skia/AnimatedDrawables.h"
#include "utils/AutoMalloc.h"
@@ -64,6 +66,32 @@ struct DisplayListOp {

static_assert(sizeof(DisplayListOp) == 4);

struct DrawImagePayload {
    explicit DrawImagePayload(Bitmap& bitmap)
            : image(bitmap.makeImage()), palette(bitmap.palette()) {
        if (bitmap.hasGainmap()) {
            auto gainmap = bitmap.gainmap();
            gainmapInfo = gainmap->info;
            gainmapImage = gainmap->bitmap->makeImage();
        }
    }

    explicit DrawImagePayload(const SkImage* image)
            : image(sk_ref_sp(image)), palette(BitmapPalette::Unknown) {}

    DrawImagePayload(const DrawImagePayload&) = default;
    DrawImagePayload(DrawImagePayload&&) = default;
    DrawImagePayload& operator=(const DrawImagePayload&) = default;
    DrawImagePayload& operator=(DrawImagePayload&&) = default;
    ~DrawImagePayload() = default;

    sk_sp<SkImage> image;
    BitmapPalette palette;

    sk_sp<SkImage> gainmapImage;
    SkGainmapInfo gainmapInfo;
};

class RecordingCanvas;

class DisplayListData final {
@@ -122,13 +150,12 @@ private:

    void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);

    void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkSamplingOptions&,
                   const SkPaint*, BitmapPalette palette);
    void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
    void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkSamplingOptions&,
                       const SkPaint*, SkCanvas::SrcRectConstraint, BitmapPalette palette);
    void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
                          SkFilterMode, const SkPaint*, BitmapPalette);
    void drawImage(DrawImagePayload&&, SkScalar, SkScalar, const SkSamplingOptions&,
                   const SkPaint*);
    void drawImageRect(DrawImagePayload&&, const SkRect*, const SkRect&, const SkSamplingOptions&,
                       const SkPaint*, SkCanvas::SrcRectConstraint);
    void drawImageLattice(DrawImagePayload&&, const SkCanvas::Lattice&, const SkRect&, SkFilterMode,
                          const SkPaint*);

    void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
                   const SkPaint&);
@@ -195,14 +222,14 @@ public:

    void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;

    void drawImage(const sk_sp<SkImage>&, SkScalar left, SkScalar top, const SkSamplingOptions&,
                   const SkPaint* paint, BitmapPalette pallete);
    void drawRippleDrawable(const skiapipeline::RippleDrawableParams& params);

    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
                       const SkSamplingOptions&, const SkPaint*, SrcRectConstraint, BitmapPalette);
    void drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, const SkRect& dst,
                          SkFilterMode, const SkPaint* paint, BitmapPalette palette);
    void drawImage(DrawImagePayload&&, SkScalar, SkScalar, const SkSamplingOptions&,
                   const SkPaint*);
    void drawImageRect(DrawImagePayload&&, const SkRect&, const SkRect&, const SkSamplingOptions&,
                       const SkPaint*, SrcRectConstraint);
    void drawImageLattice(DrawImagePayload&&, const Lattice& lattice, const SkRect&, SkFilterMode,
                          const SkPaint*);

    void onDrawImage2(const SkImage*, SkScalar, SkScalar, const SkSamplingOptions&,
                      const SkPaint*) override;
+64 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "GainmapRenderer.h"

#include <SkGainmapShader.h>

#include "Gainmap.h"
#include "Rect.h"
#include "utils/Trace.h"

#ifdef __ANDROID__
#include "renderthread/CanvasContext.h"
#endif

namespace android::uirenderer {

using namespace renderthread;

void DrawGainmapBitmap(SkCanvas* c, const sk_sp<const SkImage>& image, const SkRect& src,
                       const SkRect& dst, const SkSamplingOptions& sampling, const SkPaint* paint,
                       SkCanvas::SrcRectConstraint constraint,
                       const sk_sp<const SkImage>& gainmapImage, const SkGainmapInfo& gainmapInfo) {
    ATRACE_CALL();
#ifdef __ANDROID__
    CanvasContext* context = CanvasContext::getActiveContext();
    float targetSdrHdrRatio = context ? context->targetSdrHdrRatio() : 1.f;
    if (targetSdrHdrRatio > 1.f && gainmapImage) {
        SkPaint gainmapPaint = *paint;
        float sX = gainmapImage->width() / (float)image->width();
        float sY = gainmapImage->height() / (float)image->height();
        SkRect gainmapSrc = src;
        // TODO: Tweak rounding?
        gainmapSrc.fLeft *= sX;
        gainmapSrc.fRight *= sX;
        gainmapSrc.fTop *= sY;
        gainmapSrc.fBottom *= sY;
        // TODO: Temporary workaround for SkGainmapShader::Make not having a const variant
        sk_sp<SkImage> mutImage = sk_ref_sp(const_cast<SkImage*>(image.get()));
        sk_sp<SkImage> mutGainmap = sk_ref_sp(const_cast<SkImage*>(gainmapImage.get()));
        auto shader = SkGainmapShader::Make(mutImage, src, sampling, mutGainmap, gainmapSrc,
                                            sampling, gainmapInfo, dst, targetSdrHdrRatio,
                                            c->imageInfo().refColorSpace());
        gainmapPaint.setShader(shader);
        c->drawRect(dst, gainmapPaint);
    } else
#endif
        c->drawImageRect(image.get(), src, dst, sampling, paint, constraint);
}

}  // namespace android::uirenderer
 No newline at end of file
+33 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <SkCanvas.h>
#include <SkGainmapInfo.h>
#include <SkImage.h>
#include <SkPaint.h>

#include "hwui/Bitmap.h"

namespace android::uirenderer {

void DrawGainmapBitmap(SkCanvas* c, const sk_sp<const SkImage>& image, const SkRect& src,
                       const SkRect& dst, const SkSamplingOptions& sampling, const SkPaint* paint,
                       SkCanvas::SrcRectConstraint constraint,
                       const sk_sp<const SkImage>& gainmapImage, const SkGainmapInfo& gainmapInfo);

}  // namespace android::uirenderer
Loading