summaryrefslogtreecommitdiff
path: root/chromium/third_party/skia/gm/imagefromyuvtextures.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/gm/imagefromyuvtextures.cpp')
-rw-r--r--chromium/third_party/skia/gm/imagefromyuvtextures.cpp184
1 files changed, 124 insertions, 60 deletions
diff --git a/chromium/third_party/skia/gm/imagefromyuvtextures.cpp b/chromium/third_party/skia/gm/imagefromyuvtextures.cpp
index f9d28efe22e..bcb153458c0 100644
--- a/chromium/third_party/skia/gm/imagefromyuvtextures.cpp
+++ b/chromium/third_party/skia/gm/imagefromyuvtextures.cpp
@@ -28,7 +28,11 @@
#include "include/private/SkTo.h"
#include "src/core/SkMathPriv.h"
#include "src/core/SkYUVMath.h"
+#include "src/gpu/GrContextPriv.h"
#include "tools/Resources.h"
+#include "tools/gpu/YUVUtils.h"
+
+using sk_gpu_test::YUVABackendReleaseContext;
class GrRenderTargetContext;
@@ -46,11 +50,7 @@ protected:
SkISize onISize() override { return {1420, 610}; }
- void onOnceBeforeDraw() override {
- fRGBABmp = this->createBmpAndPlanes("images/mandrill_32.png", fYUVABmps);
- }
-
- SkBitmap createBmpAndPlanes(const char* name, SkBitmap yuvaBmps[4]) {
+ static SkBitmap CreateBmpAndPlanes(const char* name, SkBitmap yuvaBmps[4]) {
SkBitmap bmp;
if (!GetResourceAsBitmap(name, &bmp)) {
return {};
@@ -120,43 +120,22 @@ protected:
return rgbaBmp;
}
- void createYUVTextures(SkBitmap bmps[4], GrContext* context, GrBackendTexture textures[4]) {
+ static bool CreateYUVBackendTextures(GrContext* context, SkBitmap bmps[4],
+ SkYUVAIndex indices[4],
+ YUVABackendReleaseContext* beContext) {
for (int i = 0; i < 4; ++i) {
- textures[i] = context->createBackendTexture(bmps[i].pixmap(), GrRenderable::kNo,
- GrProtected::kNo);
- }
- }
-
- void createResultTexture(GrContext* context, SkISize size, GrBackendTexture* resultTexture) {
- *resultTexture = context->createBackendTexture(
- size.width(), size.height(), kRGBA_8888_SkColorType, SkColors::kTransparent,
- GrMipMapped::kNo, GrRenderable::kYes, GrProtected::kNo);
- }
-
- void deleteBackendTextures(GrContext* context, GrBackendTexture textures[], int n) {
- if (context->abandoned()) {
- return;
- }
-
- GrFlushInfo flushInfo;
- flushInfo.fFlags = kSyncCpu_GrFlushFlag;
- context->flush(flushInfo);
+ GrBackendTexture tmp = context->createBackendTexture(bmps[i].pixmap(),
+ GrRenderable::kNo,
+ GrProtected::kNo);
+ if (!tmp.isValid()) {
+ return false;
+ }
- for (int i = 0; i < n; ++i) {
- context->deleteBackendTexture(textures[i]);
+ beContext->set(i, tmp);
}
- }
- void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override {
- GrBackendTexture yuvaTextures[4];
-
- this->createYUVTextures(fYUVABmps, context, yuvaTextures);
- SkYUVAIndex indices[4];
for (int i = 0; i < 4; ++i) {
- if (!yuvaTextures[i].isValid()) {
- return;
- }
- auto chanMask = yuvaTextures[i].getBackendFormat().channelMask();
+ auto chanMask = beContext->beTexture(i).getBackendFormat().channelMask();
// We expect the single channel bitmaps to produce single channel textures.
SkASSERT(chanMask && SkIsPow2(chanMask));
if (chanMask & kGray_SkColorChannelFlag) {
@@ -167,25 +146,107 @@ protected:
indices[i].fIndex = i;
}
- // We remake this image before each draw because if any draw flattens it to RGBA then
- // all subsequent draws use the RGBA texture.
- auto makeImage1 = [&]() {
- return SkImage::MakeFromYUVATextures(context,
- kJPEG_SkYUVColorSpace,
- yuvaTextures,
- indices,
- fRGBABmp.dimensions(),
- kTopLeft_GrSurfaceOrigin);
- };
+ return true;
+ }
+
+ sk_sp<SkImage> makeYUVAImage(GrContext* context) {
+ auto releaseContext = new YUVABackendReleaseContext(context);
+ SkYUVAIndex indices[4];
+
+ if (!CreateYUVBackendTextures(context, fYUVABmps, indices, releaseContext)) {
+ YUVABackendReleaseContext::Unwind(context, releaseContext);
+ return nullptr;
+ }
- GrBackendTexture resultTexture;
- this->createResultTexture(context, fRGBABmp.dimensions(), &resultTexture);
- auto image2 = SkImage::MakeFromYUVTexturesCopyWithExternalBackend(context,
- kJPEG_SkYUVColorSpace,
- yuvaTextures,
- kTopLeft_GrSurfaceOrigin,
- resultTexture);
+ return SkImage::MakeFromYUVATextures(context,
+ kJPEG_SkYUVColorSpace,
+ releaseContext->beTextures(),
+ indices,
+ fRGBABmp.dimensions(),
+ kTopLeft_GrSurfaceOrigin,
+ nullptr,
+ YUVABackendReleaseContext::Release,
+ releaseContext);
+ }
+
+ sk_sp<SkImage> createReferenceImage(GrContext* context) {
+ auto planeReleaseContext = new YUVABackendReleaseContext(context);
+ SkYUVAIndex indices[4];
+ if (!CreateYUVBackendTextures(context, fYUVABmps, indices, planeReleaseContext)) {
+ YUVABackendReleaseContext::Unwind(context, planeReleaseContext);
+ return nullptr;
+ }
+
+ GrBackendTexture resultTexture = context->createBackendTexture(
+ fRGBABmp.dimensions().width(), fRGBABmp.dimensions().height(),
+ kRGBA_8888_SkColorType, SkColors::kTransparent,
+ GrMipMapped::kNo, GrRenderable::kYes, GrProtected::kNo);
+ if (!resultTexture.isValid()) {
+ YUVABackendReleaseContext::Unwind(context, planeReleaseContext);
+ return nullptr;
+ }
+
+ auto rgbaReleaseContext = new YUVABackendReleaseContext(context);
+ rgbaReleaseContext->set(0, resultTexture);
+
+ auto tmp = SkImage::MakeFromYUVATexturesCopyWithExternalBackend(
+ context,
+ kJPEG_SkYUVColorSpace,
+ planeReleaseContext->beTextures(),
+ indices,
+ fRGBABmp.dimensions(),
+ kTopLeft_GrSurfaceOrigin,
+ resultTexture,
+ nullptr,
+ YUVABackendReleaseContext::Release,
+ rgbaReleaseContext);
+ YUVABackendReleaseContext::Unwind(context, planeReleaseContext);
+ return tmp;
+ }
+
+ DrawResult onGpuSetup(GrContext* context, SkString* errorMsg) override {
+ if (!context || context->abandoned()) {
+ return DrawResult::kSkip;
+ }
+
+ SkASSERT(context->priv().asDirectContext());
+
+ fRGBABmp = CreateBmpAndPlanes("images/mandrill_32.png", fYUVABmps);
+
+ // We make a version of this image for each draw because, if any draw flattens it to
+ // RGBA, then all subsequent draws would use the RGBA texture.
+ for (int i = 0; i < kNumImages; ++i) {
+ fYUVAImages[i] = this->makeYUVAImage(context);
+ if (!fYUVAImages[i]) {
+ *errorMsg = "Couldn't create src YUVA image.";
+ return DrawResult::kFail;
+ }
+ }
+
+ fReferenceImage = this->createReferenceImage(context);
+ if (!fReferenceImage) {
+ *errorMsg = "Couldn't create reference YUVA image.";
+ return DrawResult::kFail;
+ }
+
+ // Some backends (e.g., Vulkan) require all work be completed for backend textures
+ // before they are deleted. Since we don't know when we'll next have access to a
+ // direct context, flush all the work now.
+ GrFlushInfo flushInfoSyncCpu;
+ flushInfoSyncCpu.fFlags = kSyncCpu_GrFlushFlag;
+ context->flush(flushInfoSyncCpu);
+ context->submit(true);
+
+ return DrawResult::kOk;
+ }
+
+ SkImage* getYUVAImage(int index) {
+ SkASSERT(index >= 0 && index < kNumImages);
+ return fYUVAImages[index].get();
+ }
+
+ void onDraw(GrContext*, GrRenderTargetContext*, SkCanvas* canvas) override {
auto draw_image = [canvas](SkImage* image, SkFilterQuality fq) -> SkSize {
if (!image) {
return {0, 0};
@@ -225,6 +286,7 @@ protected:
};
canvas->translate(kPad, kPad);
+ int imageIndex = 0;
using DrawSig = SkSize(SkImage* image, SkFilterQuality fq);
using DF = std::function<DrawSig>;
for (const auto& draw : {DF(draw_image), DF(draw_image_rect), DF(draw_image_shader)}) {
@@ -235,12 +297,12 @@ protected:
kMedium_SkFilterQuality, kHigh_SkFilterQuality}) {
canvas->save();
canvas->scale(scale, scale);
- auto s1 = draw(makeImage1().get(), fq);
+ auto s1 = draw(this->getYUVAImage(imageIndex++), fq);
canvas->restore();
canvas->translate(kPad + SkScalarCeilToScalar(scale*s1.width()), 0);
canvas->save();
canvas->scale(scale, scale);
- auto s2 = draw(image2.get(), fq);
+ auto s2 = draw(fReferenceImage.get(), fq);
canvas->restore();
canvas->translate(kPad + SkScalarCeilToScalar(scale*s2.width()), 0);
h = std::max({h, s1.height(), s2.height()});
@@ -249,15 +311,17 @@ protected:
canvas->translate(0, kPad + SkScalarCeilToScalar(scale*h));
}
}
-
- this->deleteBackendTextures(context, &resultTexture, 1);
- this->deleteBackendTextures(context, yuvaTextures, 4);
}
private:
- SkBitmap fRGBABmp;
+ SkBitmap fRGBABmp; // TODO: oddly, it looks like this could just be an SkISize
SkBitmap fYUVABmps[4];
+ // 3 draws x 3 scales x 4 filter qualities
+ static constexpr int kNumImages = 3 * 3 * 4;
+ sk_sp<SkImage> fYUVAImages[kNumImages];
+ sk_sp<SkImage> fReferenceImage;
+
static constexpr SkScalar kPad = 10.0f;
typedef GM INHERITED;