expose direct methods for decoding to an image
These are meant to contrast MakeFromEncoded(), and emphasize that it is deferred/cached, while the new methods are not. Change-Id: I83ac22394cb14cdc84ff8507a514bf708734b84f Reviewed-on: https://skia-review.googlesource.com/c/skia/+/234476 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
19754b5470
commit
a5acbf940e
@ -10,6 +10,8 @@ Milestone 78
|
|||||||
|
|
||||||
* SkDrawLooper is no longer supported in SkPaint or SkCanvas.
|
* SkDrawLooper is no longer supported in SkPaint or SkCanvas.
|
||||||
|
|
||||||
|
* SkImage: new factories: DecodeToRaster, DecodeToTexture
|
||||||
|
|
||||||
* SkImageFilter API refactor started:
|
* SkImageFilter API refactor started:
|
||||||
- Provide new factory API in include/effects/SkImageFilters
|
- Provide new factory API in include/effects/SkImageFilters
|
||||||
- Consolidated enum types to use SkTileMode and SkColorChannel
|
- Consolidated enum types to use SkTileMode and SkColorChannel
|
||||||
|
@ -154,19 +154,77 @@ public:
|
|||||||
static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator,
|
static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator,
|
||||||
const SkIRect* subset = nullptr);
|
const SkIRect* subset = nullptr);
|
||||||
|
|
||||||
/** Creates SkImage from encoded data.
|
/**
|
||||||
subset allows selecting a portion of the full image. Pass nullptr to select the entire
|
* Return an image backed by the encoded data, but attempt to defer decoding until the image
|
||||||
image; otherwise, subset must be contained by image bounds.
|
* is actually used/drawn. This deferral allows the system to cache the result, either on the
|
||||||
|
* CPU or on the GPU, depending on where the image is drawn. If memory is low, the cache may
|
||||||
SkImage is returned if format of the encoded data is recognized and supported.
|
* be purged, causing the next draw of the image to have to re-decode.
|
||||||
Recognized formats vary by platform.
|
*
|
||||||
|
* The subset parameter specifies a area within the decoded image to create the image from.
|
||||||
@param encoded data of SkImage to decode
|
* If subset is null, then the entire image is returned.
|
||||||
@param subset bounds of returned SkImage; may be nullptr
|
*
|
||||||
@return created SkImage, or nullptr
|
* This is similar to DecodeTo[Raster,Texture], but this method will attempt to defer the
|
||||||
|
* actual decode, while the DecodeTo... method explicitly decode and allocate the backend
|
||||||
|
* when the call is made.
|
||||||
|
*
|
||||||
|
* If the encoded format is not supported, or subset is outside of the bounds of the decoded
|
||||||
|
* image, nullptr is returned.
|
||||||
|
*
|
||||||
|
* @param encoded the encoded data
|
||||||
|
* @param length the number of bytes of encoded data
|
||||||
|
* @param subset the bounds of the pixels within the decoded image to return. may be null.
|
||||||
|
* @return created SkImage, or nullptr
|
||||||
*/
|
*/
|
||||||
static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr);
|
static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode the data in encoded/length into a raster image.
|
||||||
|
*
|
||||||
|
* The subset parameter specifies a area within the decoded image to create the image from.
|
||||||
|
* If subset is null, then the entire image is returned.
|
||||||
|
*
|
||||||
|
* This is similar to MakeFromEncoded, but this method will always decode immediately, and
|
||||||
|
* allocate the memory for the pixels for the lifetime of the returned image.
|
||||||
|
*
|
||||||
|
* If the encoded format is not supported, or subset is outside of the bounds of the decoded
|
||||||
|
* image, nullptr is returned.
|
||||||
|
*
|
||||||
|
* @param encoded the encoded data
|
||||||
|
* @param length the number of bytes of encoded data
|
||||||
|
* @param subset the bounds of the pixels within the decoded image to return. may be null.
|
||||||
|
* @return created SkImage, or nullptr
|
||||||
|
*/
|
||||||
|
static sk_sp<SkImage> DecodeToRaster(const void* encoded, size_t length,
|
||||||
|
const SkIRect* subset = nullptr);
|
||||||
|
static sk_sp<SkImage> DecodeToRaster(const sk_sp<SkData>& data,
|
||||||
|
const SkIRect* subset = nullptr) {
|
||||||
|
return DecodeToRaster(data->data(), data->size(), subset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode the data in encoded/length into a texture-backed image.
|
||||||
|
*
|
||||||
|
* The subset parameter specifies a area within the decoded image to create the image from.
|
||||||
|
* If subset is null, then the entire image is returned.
|
||||||
|
*
|
||||||
|
* This is similar to MakeFromEncoded, but this method will always decode immediately, and
|
||||||
|
* allocate the texture for the pixels for the lifetime of the returned image.
|
||||||
|
*
|
||||||
|
* If the encoded format is not supported, or subset is outside of the bounds of the decoded
|
||||||
|
* image, nullptr is returned.
|
||||||
|
*
|
||||||
|
* @param encoded the encoded data
|
||||||
|
* @param length the number of bytes of encoded data
|
||||||
|
* @param subset the bounds of the pixels within the decoded image to return. may be null.
|
||||||
|
* @return created SkImage, or nullptr
|
||||||
|
*/
|
||||||
|
static sk_sp<SkImage> DecodeToTexture(GrContext* ctx, const void* encoded, size_t length,
|
||||||
|
const SkIRect* subset = nullptr);
|
||||||
|
static sk_sp<SkImage> DecodeToTexture(GrContext* ctx, const sk_sp<SkData>& data,
|
||||||
|
const SkIRect* subset = nullptr) {
|
||||||
|
return DecodeToTexture(ctx, data->data(), data->size(), subset);
|
||||||
|
}
|
||||||
|
|
||||||
// Experimental
|
// Experimental
|
||||||
enum CompressionType {
|
enum CompressionType {
|
||||||
kETC1_CompressionType,
|
kETC1_CompressionType,
|
||||||
|
@ -410,6 +410,10 @@ sk_sp<SkImage> SkImage::makeRasterImage() const {
|
|||||||
|
|
||||||
#if !SK_SUPPORT_GPU
|
#if !SK_SUPPORT_GPU
|
||||||
|
|
||||||
|
sk_sp<SkImage> SkImage::DecodeToTexture(GrContext*, const void*, size_t, const SkIRect*) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
|
sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
|
||||||
const GrBackendTexture& tex, GrSurfaceOrigin origin,
|
const GrBackendTexture& tex, GrSurfaceOrigin origin,
|
||||||
SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs,
|
SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs,
|
||||||
|
@ -287,6 +287,44 @@ sk_sp<SkImage> SkImage::MakeFromGenerator(std::unique_ptr<SkImageGenerator> gene
|
|||||||
return validator ? sk_make_sp<SkImage_Lazy>(&validator) : nullptr;
|
return validator ? sk_make_sp<SkImage_Lazy>(&validator) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sk_sp<SkImage> SkImage::DecodeToRaster(const void* encoded, size_t length, const SkIRect* subset) {
|
||||||
|
// The generator will not outlive this function, so we can wrap the encoded data without copy
|
||||||
|
auto gen = SkImageGenerator::MakeFromEncoded(SkData::MakeWithoutCopy(encoded, length));
|
||||||
|
if (!gen) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
SkImageInfo info = gen->getInfo();
|
||||||
|
if (info.isEmpty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkIPoint origin = {0, 0};
|
||||||
|
if (subset) {
|
||||||
|
if (!SkIRect::MakeWH(info.width(), info.height()).contains(*subset)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
info = info.makeWH(subset->width(), subset->height());
|
||||||
|
origin = {subset->x(), subset->y()};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t rb = info.minRowBytes();
|
||||||
|
if (rb == 0) {
|
||||||
|
return nullptr; // rb was too big
|
||||||
|
}
|
||||||
|
size_t size = info.computeByteSize(rb);
|
||||||
|
if (size == SIZE_MAX) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto data = SkData::MakeUninitialized(size);
|
||||||
|
|
||||||
|
SkPixmap pmap(info, data->writable_data(), rb);
|
||||||
|
if (!generate_pixels(gen.get(), pmap, origin.x(), origin.y())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SkImage::MakeRasterData(info, data, rb);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
@ -498,4 +536,14 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
sk_sp<SkImage> SkImage::DecodeToTexture(GrContext* ctx, const void* encoded, size_t length,
|
||||||
|
const SkIRect* subset) {
|
||||||
|
// img will not survive this function, so we don't need to copy/own the encoded data,
|
||||||
|
auto img = MakeFromEncoded(SkData::MakeWithoutCopy(encoded, length), subset);
|
||||||
|
if (!img) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return img->makeTextureImage(ctx, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user