Merge "Draw gainmaps in HDR"
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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,7 +45,8 @@
|
||||
#include "SkVertices.h"
|
||||
#include "Tonemapper.h"
|
||||
#include "VectorDrawable.h"
|
||||
#include "include/gpu/GpuTypes.h" // from Skia
|
||||
#include "effects/GainmapRenderer.h"
|
||||
#include "include/gpu/GpuTypes.h" // from Skia
|
||||
#include "include/gpu/GrDirectContext.h"
|
||||
#include "pipeline/skia/AnimatedDrawables.h"
|
||||
#include "pipeline/skia/FunctorDrawable.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 {
|
||||
SkPaint newPaint = paint;
|
||||
tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
|
||||
c->drawImage(image.get(), x, y, sampling, &newPaint);
|
||||
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 {
|
||||
SkPaint newPaint = paint;
|
||||
tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
|
||||
c->drawImageRect(image.get(), src, dst, sampling, &newPaint, constraint);
|
||||
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],
|
||||
|
||||
@@ -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
libs/hwui/effects/GainmapRenderer.cpp
Normal file
64
libs/hwui/effects/GainmapRenderer.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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
|
||||
33
libs/hwui/effects/GainmapRenderer.h
Normal file
33
libs/hwui/effects/GainmapRenderer.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -208,40 +208,52 @@ void SkiaRecordingCanvas::FilterForImage(SkPaint& paint) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkiaRecordingCanvas::handleMutableImages(Bitmap& bitmap, DrawImagePayload& payload) {
|
||||
// if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
|
||||
// it is not safe to store a raw SkImage pointer, because the image object will be destroyed
|
||||
// when this function ends.
|
||||
if (!bitmap.isImmutable() && payload.image.get() && !payload.image->unique()) {
|
||||
mDisplayList->mMutableImages.push_back(payload.image.get());
|
||||
}
|
||||
|
||||
if (bitmap.hasGainmap()) {
|
||||
auto gainmapBitmap = bitmap.gainmap()->bitmap;
|
||||
// Not all DrawImagePayload receivers will store the gainmap (such as DrawImageLattice),
|
||||
// so only store it in the mutable list if it was actually recorded
|
||||
if (!gainmapBitmap->isImmutable() && payload.gainmapImage.get() &&
|
||||
!payload.gainmapImage->unique()) {
|
||||
mDisplayList->mMutableImages.push_back(payload.gainmapImage.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) {
|
||||
sk_sp<SkImage> image = bitmap.makeImage();
|
||||
auto payload = DrawImagePayload(bitmap);
|
||||
|
||||
applyLooper(
|
||||
paint,
|
||||
[&](const Paint& p) {
|
||||
mRecorder.drawImage(image, left, top, p.sampling(), &p, bitmap.palette());
|
||||
mRecorder.drawImage(DrawImagePayload(payload), left, top, p.sampling(), &p);
|
||||
},
|
||||
FilterForImage);
|
||||
|
||||
// if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
|
||||
// it is not safe to store a raw SkImage pointer, because the image object will be destroyed
|
||||
// when this function ends.
|
||||
if (!bitmap.isImmutable() && image.get() && !image->unique()) {
|
||||
mDisplayList->mMutableImages.push_back(image.get());
|
||||
}
|
||||
handleMutableImages(bitmap, payload);
|
||||
}
|
||||
|
||||
void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) {
|
||||
SkAutoCanvasRestore acr(&mRecorder, true);
|
||||
concat(matrix);
|
||||
|
||||
sk_sp<SkImage> image = bitmap.makeImage();
|
||||
auto payload = DrawImagePayload(bitmap);
|
||||
|
||||
applyLooper(
|
||||
paint,
|
||||
[&](const Paint& p) {
|
||||
mRecorder.drawImage(image, 0, 0, p.sampling(), &p, bitmap.palette());
|
||||
mRecorder.drawImage(DrawImagePayload(payload), 0, 0, p.sampling(), &p);
|
||||
},
|
||||
FilterForImage);
|
||||
|
||||
if (!bitmap.isImmutable() && image.get() && !image->unique()) {
|
||||
mDisplayList->mMutableImages.push_back(image.get());
|
||||
}
|
||||
handleMutableImages(bitmap, payload);
|
||||
}
|
||||
|
||||
void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
|
||||
@@ -250,20 +262,17 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop
|
||||
SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
|
||||
SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
|
||||
|
||||
sk_sp<SkImage> image = bitmap.makeImage();
|
||||
auto payload = DrawImagePayload(bitmap);
|
||||
|
||||
applyLooper(
|
||||
paint,
|
||||
[&](const Paint& p) {
|
||||
mRecorder.drawImageRect(image, srcRect, dstRect, p.sampling(), &p,
|
||||
SkCanvas::kFast_SrcRectConstraint, bitmap.palette());
|
||||
mRecorder.drawImageRect(DrawImagePayload(payload), srcRect, dstRect, p.sampling(),
|
||||
&p, SkCanvas::kFast_SrcRectConstraint);
|
||||
},
|
||||
FilterForImage);
|
||||
|
||||
if (!bitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty() &&
|
||||
!dstRect.isEmpty()) {
|
||||
mDisplayList->mMutableImages.push_back(image.get());
|
||||
}
|
||||
handleMutableImages(bitmap, payload);
|
||||
}
|
||||
|
||||
void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, float dstLeft,
|
||||
@@ -291,7 +300,7 @@ void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& ch
|
||||
|
||||
lattice.fBounds = nullptr;
|
||||
SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
|
||||
sk_sp<SkImage> image = bitmap.makeImage();
|
||||
auto payload = DrawImagePayload(bitmap);
|
||||
|
||||
// HWUI always draws 9-patches with linear filtering, regardless of the Paint.
|
||||
const SkFilterMode filter = SkFilterMode::kLinear;
|
||||
@@ -299,13 +308,11 @@ void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& ch
|
||||
applyLooper(
|
||||
paint,
|
||||
[&](const SkPaint& p) {
|
||||
mRecorder.drawImageLattice(image, lattice, dst, filter, &p, bitmap.palette());
|
||||
mRecorder.drawImageLattice(DrawImagePayload(payload), lattice, dst, filter, &p);
|
||||
},
|
||||
FilterForImage);
|
||||
|
||||
if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
|
||||
mDisplayList->mMutableImages.push_back(image.get());
|
||||
}
|
||||
handleMutableImages(bitmap, payload);
|
||||
}
|
||||
|
||||
double SkiaRecordingCanvas::drawAnimatedImage(AnimatedImageDrawable* animatedImage) {
|
||||
|
||||
@@ -102,6 +102,8 @@ private:
|
||||
*/
|
||||
void initDisplayList(uirenderer::RenderNode* renderNode, int width, int height);
|
||||
|
||||
void handleMutableImages(Bitmap& bitmap, DrawImagePayload& payload);
|
||||
|
||||
using INHERITED = SkiaCanvas;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user