| /* | |
| * Copyright 2023 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "src/gpu/ganesh/image/SkSpecialImage_Ganesh.h" | |
| #include "include/core/SkColorSpace.h" // IWYU pragma: keep | |
| #include "include/core/SkImage.h" | |
| #include "include/core/SkImageInfo.h" | |
| #include "include/core/SkRect.h" | |
| #include "include/core/SkSize.h" | |
| #include "include/gpu/GpuTypes.h" | |
| #include "include/gpu/ganesh/GrRecordingContext.h" | |
| #include "include/private/SkAssert.h" | |
| #include "include/private/gpu/ganesh/GrTypesPriv.h" | |
| #include "src/core/SkSpecialImage.h" | |
| #include "src/gpu/ganesh/GrSurfaceProxy.h" | |
| #include "src/gpu/ganesh/GrSurfaceProxyPriv.h" | |
| #include "src/gpu/ganesh/GrSurfaceProxyView.h" | |
| #include "src/gpu/ganesh/image/GrImageUtils.h" | |
| #include "src/gpu/ganesh/image/SkImage_Ganesh.h" | |
| #include "src/gpu/ganesh/image/SkImage_GaneshYUVA.h" | |
| #include "src/image/SkImage_Base.h" | |
| #include <cstddef> | |
| #include <tuple> | |
| #include <utility> | |
| enum SkColorType : int; | |
| class SkSpecialImage_Gpu final : public SkSpecialImage { | |
| public: | |
| SkSpecialImage_Gpu(GrRecordingContext* context, | |
| const SkIRect& subset, | |
| uint32_t uniqueID, | |
| GrSurfaceProxyView view, | |
| const SkColorInfo& colorInfo, | |
| const SkSurfaceProps& props) | |
| : SkSpecialImage(subset, uniqueID, colorInfo, props) | |
| , fContext(context) | |
| , fView(std::move(view)) {} | |
| size_t getSize() const override { return fView.proxy()->gpuMemorySize(); } | |
| bool isGaneshBacked() const override { return true; } | |
| GrRecordingContext* getContext() const override { return fContext; } | |
| GrSurfaceProxyView view(GrRecordingContext*) const { return fView; } | |
| SkISize backingStoreDimensions() const override { | |
| return fView.proxy()->backingStoreDimensions(); | |
| } | |
| sk_sp<SkSpecialImage> onMakeBackingStoreSubset(const SkIRect& subset) const override { | |
| return SkSpecialImages::MakeDeferredFromGpu( | |
| fContext, subset, this->uniqueID(), fView, this->colorInfo(), this->props()); | |
| } | |
| sk_sp<SkImage> asImage() const override { | |
| fView.proxy()->priv().exactify(); | |
| return sk_make_sp<SkImage_Ganesh>( | |
| sk_ref_sp(fContext), this->uniqueID(), fView, this->colorInfo()); | |
| } | |
| private: | |
| GrRecordingContext* fContext; | |
| GrSurfaceProxyView fView; | |
| }; | |
| namespace SkSpecialImages { | |
| sk_sp<SkSpecialImage> MakeFromTextureImage(GrRecordingContext* rContext, | |
| const SkIRect& subset, | |
| sk_sp<SkImage> image, | |
| const SkSurfaceProps& props) { | |
| if (!rContext || !image || subset.isEmpty()) { | |
| return nullptr; | |
| } | |
| SkASSERT(image->bounds().contains(subset)); | |
| GrSurfaceProxyView view; | |
| GrColorType ct; | |
| SkImage_Base* ib = as_IB(image.get()); | |
| if (ib->type() == SkImage_Base::Type::kGaneshYUVA && !subset.contains(image->bounds())) { | |
| SkRect subsetRect = SkRect::Make(subset); | |
| std::tie(view, ct) = static_cast<SkImage_GaneshYUVA*>(ib)->flattenToView( | |
| rContext, skgpu::Mipmapped::kNo, &subsetRect); | |
| } else { | |
| // This will work even if the image is a raster-backed image. | |
| std::tie(view, ct) = | |
| skgpu::ganesh::AsView(rContext, image, skgpu::Mipmapped::kNo, nullptr); | |
| } | |
| return MakeDeferredFromGpu(rContext, | |
| subset, | |
| image->uniqueID(), | |
| std::move(view), | |
| {ct, image->alphaType(), image->refColorSpace()}, | |
| props); | |
| } | |
| sk_sp<SkSpecialImage> MakeDeferredFromGpu(GrRecordingContext* context, | |
| const SkIRect& subset, | |
| uint32_t uniqueID, | |
| GrSurfaceProxyView view, | |
| const GrColorInfo& colorInfo, | |
| const SkSurfaceProps& props) { | |
| if (!context || context->abandoned() || !view.asTextureProxy()) { | |
| return nullptr; | |
| } | |
| SkASSERT(view.proxy()->backingStoreBoundsIRect().contains(subset)); | |
| SkColorType ct = GrColorTypeToSkColorType(colorInfo.colorType()); | |
| return sk_make_sp<SkSpecialImage_Gpu>( | |
| context, | |
| subset, | |
| uniqueID, | |
| std::move(view), | |
| SkColorInfo(ct, colorInfo.alphaType(), colorInfo.refColorSpace()), | |
| props); | |
| } | |
| GrSurfaceProxyView AsView(GrRecordingContext* context, const SkSpecialImage* img) { | |
| if (!context || !img || !img->isGaneshBacked()) { | |
| return {}; | |
| } | |
| auto grImg = static_cast<const SkSpecialImage_Gpu*>(img); | |
| return grImg->view(context); | |
| } | |
| } // namespace SkSpecialImages |