blob: f4dcc5f4279a2e63c3db6d19196b63524bbd23cb [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
28 static std::unique_ptr<LazyYUVImage> Make(sk_sp<SkData> data);
29
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];
41
42 // Memoized SkImage formed with planes
43 sk_sp<SkImage> fYUVImage;
Michael Ludwigd9958f82019-03-21 13:08:36 -040044
Brian Salomonefb5f072020-07-28 21:06:43 -040045 LazyYUVImage() = default;
Michael Ludwigd9958f82019-03-21 13:08:36 -040046
47 bool reset(sk_sp<SkData> data);
48
Brian Salomonefb5f072020-07-28 21:06:43 -040049 bool ensureYUVImage(GrRecordingContext* rContext);
Michael Ludwigd9958f82019-03-21 13:08:36 -040050};
51
Robert Phillipsf105d382020-06-19 14:27:14 -040052// A helper for managing the lifetime of backend textures for YUVA images.
53class YUVABackendReleaseContext {
54public:
Robert Phillips98c39ba2020-06-26 10:01:19 -040055 static GrGpuFinishedProc CreationCompleteProc(int index);
56
Robert Phillipsf105d382020-06-19 14:27:14 -040057 // A stock 'TextureReleaseProc' to use with this class
58 static void Release(void* releaseContext) {
59 auto beContext = reinterpret_cast<YUVABackendReleaseContext*>(releaseContext);
60
61 delete beContext;
62 }
63
64 // Given how and when backend textures are created, just deleting this object often
65 // isn't enough. This helper encapsulates the extra work needed.
Robert Phillips057c33f2020-07-17 11:59:01 -040066 static void Unwind(GrDirectContext*, YUVABackendReleaseContext* beContext, bool fullFlush);
Robert Phillipsf105d382020-06-19 14:27:14 -040067
Robert Phillips057c33f2020-07-17 11:59:01 -040068 YUVABackendReleaseContext(GrDirectContext*);
Robert Phillipsf105d382020-06-19 14:27:14 -040069 ~YUVABackendReleaseContext();
70
71 void set(int index, const GrBackendTexture& beTex) {
72 SkASSERT(index >= 0 && index < 4);
73 SkASSERT(!fBETextures[index].isValid());
74 SkASSERT(beTex.isValid());
75
76 fBETextures[index] = beTex;
77 }
78
Robert Phillips98c39ba2020-06-26 10:01:19 -040079 void setCreationComplete(int index) {
80 SkASSERT(index >= 0 && index < 4);
81 // In GL, the finished proc can fire before the backend texture is returned to the client
82 // SkASSERT(fBETextures[index].isValid());
83
84 fCreationComplete[index] = true;
85 }
86
87 bool creationCompleted() const {
88 for (int i = 0; i < 4; ++i) {
89 if (fBETextures[i].isValid() && !fCreationComplete[i]) {
90 return false;
91 }
92 }
93
94 return true;
95 }
96
Robert Phillipsf105d382020-06-19 14:27:14 -040097 const GrBackendTexture* beTextures() const { return fBETextures; }
98
99 const GrBackendTexture& beTexture(int index) {
100 SkASSERT(index >= 0 && index < 4);
101 SkASSERT(fBETextures[index].isValid());
102 return fBETextures[index];
103 }
104
105private:
Robert Phillips057c33f2020-07-17 11:59:01 -0400106 GrDirectContext* fDContext;
Robert Phillipsf105d382020-06-19 14:27:14 -0400107 GrBackendTexture fBETextures[4];
Robert Phillips98c39ba2020-06-26 10:01:19 -0400108 bool fCreationComplete[4] = { false };
Robert Phillipsf105d382020-06-19 14:27:14 -0400109};
110
111
Michael Ludwigd9958f82019-03-21 13:08:36 -0400112} // namespace sk_gpu_test
113
114#endif // YUVUtils_DEFINED