6c15cc7e9d
This tries to match the behavior you would see if you rendered directly to a canvas without going through this round-trip. Specifically, mips are built in the same way that they would be according to the context's internal logic. To make things clearer, the user passes in the color space of the destination surface, not our (internal) enum. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3526 Change-Id: If8c61500d34ae712227da0284f3a80cacf84113a Reviewed-on: https://skia-review.googlesource.com/3526 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
186 lines
6.9 KiB
C++
186 lines
6.9 KiB
C++
/*
|
|
* Copyright 2016 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
#include <vector>
|
|
|
|
#include "gm.h"
|
|
#include "SkMipMap.h"
|
|
#include "Resources.h"
|
|
|
|
#if SK_SUPPORT_GPU
|
|
#include "GrContext.h"
|
|
|
|
// Helper function that uploads the given SkImage using MakdeFromDeferredTextureImageData and then
|
|
// draws the uploaded version at the specified coordinates.
|
|
static void DrawDeferredTextureImageData(SkCanvas* canvas,
|
|
SkImage::DeferredTextureImageUsageParams* params) {
|
|
GrContext* context = canvas->getGrContext();
|
|
if (!context) {
|
|
skiagm::GM::DrawGpuOnlyMessage(canvas);
|
|
return;
|
|
}
|
|
SkAutoTUnref<GrContextThreadSafeProxy> proxy(context->threadSafeProxy());
|
|
|
|
|
|
|
|
sk_sp<SkImage> encodedImage = GetResourceAsImage("mandrill_512.png");
|
|
if (!encodedImage) {
|
|
SkDebugf("\nCould not load resource.\n");
|
|
return;
|
|
}
|
|
|
|
size_t requiredMemoryInBytes = encodedImage->getDeferredTextureImageData(
|
|
*proxy, params, 1, nullptr, canvas->imageInfo().colorSpace());
|
|
if (requiredMemoryInBytes == 0) {
|
|
SkDebugf("\nCould not create DeferredTextureImageData.\n");
|
|
return;
|
|
}
|
|
|
|
std::vector<uint8_t> memory;
|
|
memory.resize(requiredMemoryInBytes);
|
|
encodedImage->getDeferredTextureImageData(
|
|
*proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace());
|
|
sk_sp<SkImage> uploadedEncodedImage = SkImage::MakeFromDeferredTextureImageData(
|
|
context, memory.data(), SkBudgeted::kNo);
|
|
|
|
canvas->drawImage(uploadedEncodedImage, 10, 10);
|
|
|
|
|
|
|
|
SkBitmap bitmap;
|
|
if (!GetResourceAsBitmap("mandrill_512.png", &bitmap)) {
|
|
SkDebugf("\nCould not decode resource.\n");
|
|
return;
|
|
}
|
|
sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap);
|
|
|
|
requiredMemoryInBytes = decodedImage->getDeferredTextureImageData(
|
|
*proxy, params, 1, nullptr, canvas->imageInfo().colorSpace());
|
|
if (requiredMemoryInBytes == 0) {
|
|
SkDebugf("\nCould not create DeferredTextureImageData.\n");
|
|
return;
|
|
}
|
|
|
|
memory.resize(requiredMemoryInBytes);
|
|
decodedImage->getDeferredTextureImageData(
|
|
*proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace());
|
|
sk_sp<SkImage> uploadedDecodedImage = SkImage::MakeFromDeferredTextureImageData(
|
|
context, memory.data(), SkBudgeted::kNo);
|
|
|
|
canvas->drawImage(uploadedDecodedImage, 512 + 20, 10);
|
|
}
|
|
|
|
static void DrawDeferredTextureImageMipMapTree(SkCanvas* canvas, SkImage* image,
|
|
SkImage::DeferredTextureImageUsageParams* params) {
|
|
GrContext* context = canvas->getGrContext();
|
|
if (!context) {
|
|
skiagm::GM::DrawGpuOnlyMessage(canvas);
|
|
return;
|
|
}
|
|
SkAutoTUnref<GrContextThreadSafeProxy> proxy(context->threadSafeProxy());
|
|
|
|
SkPaint paint;
|
|
paint.setFilterQuality(params->fQuality);
|
|
|
|
int mipLevelCount = SkMipMap::ComputeLevelCount(512, 512);
|
|
size_t requiredMemoryInBytes = image->getDeferredTextureImageData(
|
|
*proxy, params, 1, nullptr, canvas->imageInfo().colorSpace());
|
|
if (requiredMemoryInBytes == 0) {
|
|
SkDebugf("\nCould not create DeferredTextureImageData.\n");
|
|
return;
|
|
}
|
|
|
|
std::vector<uint8_t> memory;
|
|
memory.resize(requiredMemoryInBytes);
|
|
image->getDeferredTextureImageData(
|
|
*proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace());
|
|
sk_sp<SkImage> uploadedImage = SkImage::MakeFromDeferredTextureImageData(
|
|
context, memory.data(), SkBudgeted::kNo);
|
|
|
|
// draw a column using deferred texture images
|
|
SkScalar offsetHeight = 10.f;
|
|
// handle base mipmap level
|
|
canvas->save();
|
|
canvas->translate(10.f, offsetHeight);
|
|
canvas->drawImage(uploadedImage, 0, 0, &paint);
|
|
canvas->restore();
|
|
offsetHeight += 512 + 10;
|
|
// handle generated mipmap levels
|
|
for (int i = 0; i < mipLevelCount; i++) {
|
|
SkISize mipSize = SkMipMap::ComputeLevelSize(512, 512, i);
|
|
canvas->save();
|
|
canvas->translate(10.f, offsetHeight);
|
|
canvas->scale(mipSize.width() / 512.f, mipSize.height() / 512.f);
|
|
canvas->drawImage(uploadedImage, 0, 0, &paint);
|
|
canvas->restore();
|
|
offsetHeight += mipSize.height() + 10;
|
|
}
|
|
|
|
// draw a column using SkImage
|
|
offsetHeight = 10;
|
|
// handle base mipmap level
|
|
canvas->save();
|
|
canvas->translate(512.f + 20.f, offsetHeight);
|
|
canvas->drawImage(image, 0, 0, &paint);
|
|
canvas->restore();
|
|
offsetHeight += 512 + 10;
|
|
// handle generated mipmap levels
|
|
for (int i = 0; i < mipLevelCount; i++) {
|
|
SkISize mipSize = SkMipMap::ComputeLevelSize(512, 512, i);
|
|
canvas->save();
|
|
canvas->translate(512.f + 20.f, offsetHeight);
|
|
canvas->scale(mipSize.width() / 512.f, mipSize.height() / 512.f);
|
|
canvas->drawImage(image, 0, 0, &paint);
|
|
canvas->restore();
|
|
offsetHeight += mipSize.height() + 10;
|
|
}
|
|
}
|
|
|
|
DEF_SIMPLE_GM(deferred_texture_image_none, canvas, 512 + 512 + 30, 512 + 20) {
|
|
auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f),
|
|
kNone_SkFilterQuality, 0);
|
|
DrawDeferredTextureImageData(canvas, ¶ms);
|
|
}
|
|
|
|
DEF_SIMPLE_GM(deferred_texture_image_low, canvas, 512 + 512 + 30, 512 + 20) {
|
|
auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f),
|
|
kLow_SkFilterQuality, 0);
|
|
DrawDeferredTextureImageData(canvas, ¶ms);
|
|
}
|
|
|
|
DEF_SIMPLE_GM(deferred_texture_image_medium_encoded, canvas, 512 + 512 + 30, 1110) {
|
|
sk_sp<SkImage> encodedImage = GetResourceAsImage("mandrill_512.png");
|
|
if (!encodedImage) {
|
|
SkDebugf("\nCould not load resource.\n");
|
|
return;
|
|
}
|
|
|
|
auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f),
|
|
kMedium_SkFilterQuality, 0);
|
|
DrawDeferredTextureImageMipMapTree(canvas, encodedImage.get(), ¶ms);
|
|
}
|
|
|
|
DEF_SIMPLE_GM(deferred_texture_image_medium_decoded, canvas, 512 + 512 + 30, 1110) {
|
|
SkBitmap bitmap;
|
|
if (!GetResourceAsBitmap("mandrill_512.png", &bitmap)) {
|
|
SkDebugf("\nCould not decode resource.\n");
|
|
return;
|
|
}
|
|
sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap);
|
|
|
|
auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f),
|
|
kMedium_SkFilterQuality, 0);
|
|
DrawDeferredTextureImageMipMapTree(canvas, decodedImage.get(), ¶ms);
|
|
}
|
|
|
|
DEF_SIMPLE_GM(deferred_texture_image_high, canvas, 512 + 512 + 30, 512 + 20) {
|
|
auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f),
|
|
kHigh_SkFilterQuality, 0);
|
|
DrawDeferredTextureImageData(canvas, ¶ms);
|
|
}
|
|
|
|
#endif
|