blob: fe1c48b963799b6f35b4bd87965eb2ede1c76ae8 [file] [log] [blame]
/*
* Copyright 2022 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/graphite/SpecialImage_Graphite.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "src/core/SkSpecialImage.h"
#include "src/gpu/graphite/Device.h"
#include "src/gpu/graphite/Image_Graphite.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/gpu/graphite/TextureUtils.h"
namespace skgpu::graphite {
class SkSpecialImage_Graphite final : public SkSpecialImage {
public:
SkSpecialImage_Graphite(const SkIRect& subset,
uint32_t uniqueID,
TextureProxyView view,
const SkColorInfo& colorInfo,
const SkSurfaceProps& props)
: SkSpecialImage(subset, uniqueID, colorInfo, props)
, fTextureProxyView(std::move(view)) {
}
size_t getSize() const override {
// TODO: return VRAM size here
return 0;
}
bool isGraphiteBacked() const override { return true; }
TextureProxyView textureProxyView() const { return fTextureProxyView; }
sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const override {
return SkSpecialImages::MakeGraphite(subset,
this->uniqueID(),
fTextureProxyView,
this->colorInfo(),
this->props());
}
sk_sp<SkImage> asImage() const override {
return sk_make_sp<Image>(this->uniqueID(), fTextureProxyView, this->colorInfo());
}
private:
TextureProxyView fTextureProxyView;
};
} // namespace skgpu::graphite
namespace SkSpecialImages {
sk_sp<SkSpecialImage> MakeGraphite(skgpu::graphite::Recorder* recorder,
const SkIRect& subset,
sk_sp<SkImage> image,
const SkSurfaceProps& props) {
if (!recorder || !image || subset.isEmpty()) {
return nullptr;
}
SkASSERT(image->bounds().contains(subset));
// This will work even if the image is a raster-backed image and the Recorder's
// client ImageProvider does a valid upload.
if (!as_IB(image)->isGraphiteBacked()) {
auto [graphiteImage, _] =
skgpu::graphite::GetGraphiteBacked(recorder, image.get(), {});
if (!graphiteImage) {
return nullptr;
}
image = graphiteImage;
}
auto [view, ct] = skgpu::graphite::AsView(recorder, image.get(), skgpu::Mipmapped::kNo);
return MakeGraphite(subset, image->uniqueID(), std::move(view),
{ct, image->alphaType(), image->refColorSpace()}, props);
}
sk_sp<SkSpecialImage> MakeGraphite(const SkIRect& subset,
uint32_t uniqueID,
skgpu::graphite::TextureProxyView view,
const SkColorInfo& colorInfo,
const SkSurfaceProps& props) {
if (!view) {
return nullptr;
}
SkASSERT(SkIRect::MakeSize(view.dimensions()).contains(subset));
return sk_make_sp<skgpu::graphite::SkSpecialImage_Graphite>(subset, uniqueID,
std::move(view), colorInfo, props);
}
skgpu::graphite::TextureProxyView AsTextureProxyView(const SkSpecialImage* img) {
if (!img || !img->isGraphiteBacked()) {
return {};
}
auto grImg = static_cast<const skgpu::graphite::SkSpecialImage_Graphite*>(img);
return grImg->textureProxyView();
}
} // namespace SkSpecialImages