Now that picture backed images always play back their contents to a tagged surface, we can always construct them with either the destination surface color space or the xform canvas color space, and get the same results. To ensure that they always behave sensibly, fallback to sRGB if neither color space is present. With those changes, the caching and setup can be much simpler: the source of the color space is irrelevant. Also, switch to using our new hash data, rather than the suspicious caching based on pointers. Finally, now that we enforce a color space on all of these generators, the back-door factory can go away, along with the header. PS: Fix a spelling error. Bug: skia: Change-Id: I40fd2d35f2b3e6f8a1657d47f57127adacb80a80 Reviewed-on: https://skia-review.googlesource.com/c/163249 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
120 lines
4.1 KiB
C++
120 lines
4.1 KiB
C++
/*
|
|
* 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 "SkImage_Base.h"
|
|
#include "SkImageGenerator.h"
|
|
#include "SkCanvas.h"
|
|
#include "SkMakeUnique.h"
|
|
#include "SkMatrix.h"
|
|
#include "SkPaint.h"
|
|
#include "SkPicture.h"
|
|
#include "SkSurface.h"
|
|
#include "SkTLazy.h"
|
|
|
|
class SkPictureImageGenerator : public SkImageGenerator {
|
|
public:
|
|
SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture>, const SkMatrix*,
|
|
const SkPaint*);
|
|
|
|
protected:
|
|
bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options& opts)
|
|
override;
|
|
|
|
#if SK_SUPPORT_GPU
|
|
TexGenType onCanGenerateTexture() const override { return TexGenType::kExpensive; }
|
|
sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&, const SkIPoint&,
|
|
bool willNeedMipMaps) override;
|
|
#endif
|
|
|
|
private:
|
|
sk_sp<SkPicture> fPicture;
|
|
SkMatrix fMatrix;
|
|
SkTLazy<SkPaint> fPaint;
|
|
|
|
typedef SkImageGenerator INHERITED;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
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) {
|
|
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.width(), size.height(), colorType,
|
|
kPremul_SkAlphaType, std::move(colorSpace));
|
|
return std::unique_ptr<SkImageGenerator>(
|
|
new SkPictureImageGenerator(info, std::move(picture), matrix, paint));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture> picture,
|
|
const SkMatrix* matrix, const SkPaint* paint)
|
|
: INHERITED(info)
|
|
, fPicture(std::move(picture)) {
|
|
|
|
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) {
|
|
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
|
|
std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, rowBytes, &props);
|
|
if (!canvas) {
|
|
return false;
|
|
}
|
|
canvas->clear(0);
|
|
canvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if SK_SUPPORT_GPU
|
|
sk_sp<GrTextureProxy> SkPictureImageGenerator::onGenerateTexture(
|
|
GrContext* ctx, const SkImageInfo& info, const SkIPoint& origin, bool willNeedMipMaps) {
|
|
SkASSERT(ctx);
|
|
|
|
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
|
|
sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kYes, info, 0,
|
|
kTopLeft_GrSurfaceOrigin, &props,
|
|
willNeedMipMaps));
|
|
if (!surface) {
|
|
return nullptr;
|
|
}
|
|
|
|
SkMatrix matrix = fMatrix;
|
|
matrix.postTranslate(-origin.x(), -origin.y());
|
|
surface->getCanvas()->clear(0);
|
|
surface->getCanvas()->drawPicture(fPicture.get(), &matrix, fPaint.getMaybeNull());
|
|
sk_sp<SkImage> image(surface->makeImageSnapshot());
|
|
if (!image) {
|
|
return nullptr;
|
|
}
|
|
sk_sp<GrTextureProxy> proxy = as_IB(image)->asTextureProxyRef();
|
|
SkASSERT(!willNeedMipMaps || GrMipMapped::kYes == proxy->mipMapped());
|
|
return proxy;
|
|
}
|
|
#endif
|