blob: 97b57a7d57fb2c2120141159a1820ffc405e9f22 [file] [log] [blame]
Michael Ludwigd9958f82019-03-21 13:08:36 -04001/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef YUVUtils_DEFINED
9#define YUVUtils_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkImage.h"
12#include "include/core/SkYUVAIndex.h"
13#include "include/core/SkYUVASizeInfo.h"
Robert Phillipsf105d382020-06-19 14:27:14 -040014#include "include/gpu/GrBackendSurface.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/core/SkAutoMalloc.h"
Michael Ludwigd9958f82019-03-21 13:08:36 -040016
17class SkData;
18
19namespace sk_gpu_test {
20
21// Utility that decodes a JPEG but preserves the YUVA8 planes in the image, and uses
22// MakeFromYUVAPixmaps to create a GPU multiplane YUVA image for a context. It extracts the planar
23// data once, and lazily creates the actual SkImage when the GrContext is provided (and refreshes
24// the image if the context has changed, as in Viewer)
25class LazyYUVImage {
26public:
27 // Returns null if the data could not be extracted into YUVA8 planes
Brian Salomon6db78b82020-07-31 08:57:48 -040028 static std::unique_ptr<LazyYUVImage> Make(sk_sp<SkData> data, GrMipmapped = GrMipmapped::kNo);
Michael Ludwigd9958f82019-03-21 13:08:36 -040029
Brian Salomonefb5f072020-07-28 21:06:43 -040030 sk_sp<SkImage> refImage(GrRecordingContext* rContext);
Michael Ludwigd9958f82019-03-21 13:08:36 -040031
Brian Salomonefb5f072020-07-28 21:06:43 -040032 const SkImage* getImage(GrRecordingContext* rContext);
Michael Ludwigd9958f82019-03-21 13:08:36 -040033
34private:
35 // Decoded YUV data
36 SkYUVASizeInfo fSizeInfo;
37 SkYUVColorSpace fColorSpace;
38 SkYUVAIndex fComponents[SkYUVAIndex::kIndexCount];
39 SkAutoMalloc fPlaneData;
40 SkPixmap fPlanes[SkYUVASizeInfo::kMaxCount];
Brian Salomon6db78b82020-07-31 08:57:48 -040041 GrMipmapped fMipmapped;
Michael Ludwigd9958f82019-03-21 13:08:36 -040042
43 // Memoized SkImage formed with planes
44 sk_sp<SkImage> fYUVImage;
Michael Ludwigd9958f82019-03-21 13:08:36 -040045
Brian Salomonefb5f072020-07-28 21:06:43 -040046 LazyYUVImage() = default;
Michael Ludwigd9958f82019-03-21 13:08:36 -040047
Brian Salomon6db78b82020-07-31 08:57:48 -040048 bool reset(sk_sp<SkData> data, GrMipmapped);
Michael Ludwigd9958f82019-03-21 13:08:36 -040049
Brian Salomonefb5f072020-07-28 21:06:43 -040050 bool ensureYUVImage(GrRecordingContext* rContext);
Michael Ludwigd9958f82019-03-21 13:08:36 -040051};
52
Robert Phillipsf105d382020-06-19 14:27:14 -040053// A helper for managing the lifetime of backend textures for YUVA images.
54class YUVABackendReleaseContext {
55public:
Robert Phillips98c39ba2020-06-26 10:01:19 -040056 static GrGpuFinishedProc CreationCompleteProc(int index);
57
Robert Phillipsf105d382020-06-19 14:27:14 -040058 // A stock 'TextureReleaseProc' to use with this class
59 static void Release(void* releaseContext) {
60 auto beContext = reinterpret_cast<YUVABackendReleaseContext*>(releaseContext);
61
62 delete beContext;
63 }
64
65 // Given how and when backend textures are created, just deleting this object often
66 // isn't enough. This helper encapsulates the extra work needed.
Robert Phillips057c33f2020-07-17 11:59:01 -040067 static void Unwind(GrDirectContext*, YUVABackendReleaseContext* beContext, bool fullFlush);
Robert Phillipsf105d382020-06-19 14:27:14 -040068
Robert Phillips057c33f2020-07-17 11:59:01 -040069 YUVABackendReleaseContext(GrDirectContext*);
Robert Phillipsf105d382020-06-19 14:27:14 -040070 ~YUVABackendReleaseContext();
71
72 void set(int index, const GrBackendTexture& beTex) {
73 SkASSERT(index >= 0 && index < 4);
74 SkASSERT(!fBETextures[index].isValid());
75 SkASSERT(beTex.isValid());
76
77 fBETextures[index] = beTex;
78 }
79
Robert Phillips98c39ba2020-06-26 10:01:19 -040080 void setCreationComplete(int index) {
81 SkASSERT(index >= 0 && index < 4);
82 // In GL, the finished proc can fire before the backend texture is returned to the client
83 // SkASSERT(fBETextures[index].isValid());
84
85 fCreationComplete[index] = true;
86 }
87
88 bool creationCompleted() const {
89 for (int i = 0; i < 4; ++i) {
90 if (fBETextures[i].isValid() && !fCreationComplete[i]) {
91 return false;
92 }
93 }
94
95 return true;
96 }
97
Robert Phillipsf105d382020-06-19 14:27:14 -040098 const GrBackendTexture* beTextures() const { return fBETextures; }
99
100 const GrBackendTexture& beTexture(int index) {
101 SkASSERT(index >= 0 && index < 4);
102 SkASSERT(fBETextures[index].isValid());
103 return fBETextures[index];
104 }
105
106private:
Robert Phillips057c33f2020-07-17 11:59:01 -0400107 GrDirectContext* fDContext;
Robert Phillipsf105d382020-06-19 14:27:14 -0400108 GrBackendTexture fBETextures[4];
Robert Phillips98c39ba2020-06-26 10:01:19 -0400109 bool fCreationComplete[4] = { false };
Robert Phillipsf105d382020-06-19 14:27:14 -0400110};
111
112
Michael Ludwigd9958f82019-03-21 13:08:36 -0400113} // namespace sk_gpu_test
114
115#endif // YUVUtils_DEFINED