blob: 1018af8a389e5ba7c4e2be73ae864fb0d7dd4202 [file] [log] [blame]
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImageGenerator.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkSurface.h"
#include "src/base/SkTLazy.h"
#include "src/image/SkImage_Base.h"
#if SK_SUPPORT_GPU
#include "src/gpu/ganesh/GrTextureProxy.h"
#endif
class SkPictureImageGenerator : public SkImageGenerator {
public:
SkPictureImageGenerator(const SkImageInfo&, sk_sp<SkPicture>, const SkMatrix*,
const SkPaint*, const SkSurfaceProps&);
protected:
bool onGetPixels(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&) override;
#if SK_SUPPORT_GPU
GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&,
GrMipmapped, GrImageTexGenPolicy) override;
#endif
#if SK_GRAPHITE_ENABLED
sk_sp<SkImage> onMakeTextureImage(skgpu::graphite::Recorder*,
const SkImageInfo&,
skgpu::graphite::Mipmapped) override;
#endif
private:
sk_sp<SkPicture> fPicture;
SkMatrix fMatrix;
SkTLazy<SkPaint> fPaint;
SkSurfaceProps fProps;
using INHERITED = SkImageGenerator;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<SkImageGenerator>
SkImageGenerator::MakeFromPicture(const SkISize& size, sk_sp<SkPicture> picture,
const SkMatrix* matrix, const SkPaint* paint,
SkImage::BitDepth bitDepth, sk_sp<SkColorSpace> colorSpace,
SkSurfaceProps props) {
if (!picture || !colorSpace || size.isEmpty()) {
return nullptr;
}
SkColorType colorType = kN32_SkColorType;
if (SkImage::BitDepth::kF16 == bitDepth) {
colorType = kRGBA_F16_SkColorType;
}
SkImageInfo info =
SkImageInfo::Make(size, colorType, kPremul_SkAlphaType, std::move(colorSpace));
return std::unique_ptr<SkImageGenerator>(
new SkPictureImageGenerator(info, std::move(picture), matrix, paint, props));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture> picture,
const SkMatrix* matrix, const SkPaint* paint,
const SkSurfaceProps& props)
: SkImageGenerator(info)
, fPicture(std::move(picture))
, fProps(props) {
if (matrix) {
fMatrix = *matrix;
} else {
fMatrix.reset();
}
if (paint) {
fPaint.set(*paint);
}
}
bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
const Options& opts) {
std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, rowBytes, &fProps);
if (!canvas) {
return false;
}
canvas->clear(0);
canvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
#include "include/gpu/GrRecordingContext.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/SkGr.h"
GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx,
const SkImageInfo& info,
GrMipmapped mipmapped,
GrImageTexGenPolicy texGenPolicy) {
SkASSERT(ctx);
skgpu::Budgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
? skgpu::Budgeted::kNo
: skgpu::Budgeted::kYes;
auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0, kTopLeft_GrSurfaceOrigin,
&fProps, mipmapped == GrMipmapped::kYes);
if (!surface) {
return {};
}
surface->getCanvas()->clear(SkColors::kTransparent);
surface->getCanvas()->drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
sk_sp<SkImage> image(surface->makeImageSnapshot());
if (!image) {
return {};
}
auto [view, ct] = as_IB(image)->asView(ctx, mipmapped);
SkASSERT(view);
SkASSERT(mipmapped == GrMipmapped::kNo ||
view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
return view;
}
#endif // SK_SUPPORT_GPU
///////////////////////////////////////////////////////////////////////////////////////////////////
#if SK_GRAPHITE_ENABLED
#include "src/gpu/graphite/Log.h"
sk_sp<SkImage> SkPictureImageGenerator::onMakeTextureImage(skgpu::graphite::Recorder* recorder,
const SkImageInfo& info,
skgpu::graphite::Mipmapped mipmapped) {
using namespace skgpu::graphite;
sk_sp<SkSurface> surface = SkSurface::MakeGraphite(recorder, info, mipmapped);
if (!surface) {
SKGPU_LOG_E("Failed to create Surface");
return nullptr;
}
surface->getCanvas()->clear(SkColors::kTransparent);
surface->getCanvas()->drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
return surface->asImage();
}
#endif // SK_GRAPHITE_ENABLED