diff options
author | 2023-02-01 20:57:44 -0500 | |
---|---|---|
committer | 2023-02-01 21:58:34 -0500 | |
commit | 115195e3561af010fac687f780506c7090824ca3 (patch) | |
tree | ab30151ce48fe9deda365c84228b5fb11cb6e1f3 | |
parent | 255dc584a294f874b10aa4aa360bc6f36ec86d82 (diff) |
Draw gainmaps in HDR
Test: manual
Bug: 266628247
Change-Id: Iad0234089913637f9cddcb39d8fc32badabf3865
-rw-r--r-- | libs/hwui/Android.bp | 1 | ||||
-rw-r--r-- | libs/hwui/RecordingCanvas.cpp | 133 | ||||
-rw-r--r-- | libs/hwui/RecordingCanvas.h | 67 | ||||
-rw-r--r-- | libs/hwui/effects/GainmapRenderer.cpp | 64 | ||||
-rw-r--r-- | libs/hwui/effects/GainmapRenderer.h | 33 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp | 57 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaRecordingCanvas.h | 2 |
7 files changed, 259 insertions, 98 deletions
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index eeed2267d0c3..9e3f115762a1 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -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", diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 430e69e1ed3f..659aec0fdf58 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.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], diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index b7d4dc90f429..8409e136b57b 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -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; diff --git a/libs/hwui/effects/GainmapRenderer.cpp b/libs/hwui/effects/GainmapRenderer.cpp new file mode 100644 index 000000000000..a544ae88f9be --- /dev/null +++ b/libs/hwui/effects/GainmapRenderer.cpp @@ -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
\ No newline at end of file diff --git a/libs/hwui/effects/GainmapRenderer.h b/libs/hwui/effects/GainmapRenderer.h new file mode 100644 index 000000000000..7c56d94d9776 --- /dev/null +++ b/libs/hwui/effects/GainmapRenderer.h @@ -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 diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index c9d79ab633a0..e1c8877a8b7a 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -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) { diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h index 7844e2cc2a73..3fd8fa3aa9a9 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h @@ -102,6 +102,8 @@ private: */ void initDisplayList(uirenderer::RenderNode* renderNode, int width, int height); + void handleMutableImages(Bitmap& bitmap, DrawImagePayload& payload); + using INHERITED = SkiaCanvas; }; |