1/*
2 * Copyright 2018 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 SkImage_GpuYUVA_DEFINED
9#define SkImage_GpuYUVA_DEFINED
10
11#include "include/gpu/GrBackendSurface.h"
12#include "include/gpu/GrContext.h"
13#include "src/core/SkCachedData.h"
14#include "src/image/SkImage_GpuBase.h"
15
16class GrTexture;
17struct SkYUVASizeInfo;
18
19// Wraps the 3 or 4 planes of a YUVA image for consumption by the GPU.
20// Initially any direct rendering will be done by passing the individual planes to a shader.
21// Once any method requests a flattened image (e.g., onReadPixels), the flattened RGB
22// proxy will be stored and used for any future rendering.
23class SkImage_GpuYUVA : public SkImage_GpuBase {
24public:
25 friend class GrYUVAImageTextureMaker;
26
27 SkImage_GpuYUVA(sk_sp<GrContext>,
28 SkISize size,
29 uint32_t uniqueID,
30 SkYUVColorSpace,
31 GrSurfaceProxyView views[],
32 int numViews,
33 const SkYUVAIndex[4],
34 GrSurfaceOrigin,
35 sk_sp<SkColorSpace>);
36
37 GrSemaphoresSubmitted onFlush(GrContext*, const GrFlushInfo&) override;
38
39 // This returns the single backing proxy if the YUV channels have already been flattened but
40 // nullptr if they have not.
41 GrTextureProxy* peekProxy() const override;
42
43 const GrSurfaceProxyView* view(GrRecordingContext* context) const override;
44
45 bool onIsTextureBacked() const override {
46 SkASSERT(fViews[0].proxy() || fRGBView.proxy());
47 return true;
48 }
49
50 sk_sp<SkImage> onMakeColorTypeAndColorSpace(GrRecordingContext*,
51 SkColorType, sk_sp<SkColorSpace>) const final;
52
53 sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const final;
54
55 virtual bool isYUVA() const override { return true; }
56
57 bool setupMipmapsForPlanes(GrRecordingContext*) const;
58
59 // Returns a ref-ed texture proxy view with miplevels
60 GrSurfaceProxyView refMippedView(GrRecordingContext*) const;
61
62#if GR_TEST_UTILS
63 bool testingOnly_IsFlattened() const {
64 // We should only have the flattened proxy or the planar proxies at one point in time.
65 SkASSERT(SkToBool(fRGBView.proxy()) != SkToBool(fViews[0].proxy()));
66 return SkToBool(fRGBView.proxy());
67 }
68#endif
69
70 /**
71 * This is the implementation of SkDeferredDisplayListRecorder::makeYUVAPromiseTexture.
72 */
73 static sk_sp<SkImage> MakePromiseYUVATexture(GrContext* context,
74 SkYUVColorSpace yuvColorSpace,
75 const GrBackendFormat yuvaFormats[],
76 const SkISize yuvaSizes[],
77 const SkYUVAIndex yuvaIndices[4],
78 int width,
79 int height,
80 GrSurfaceOrigin imageOrigin,
81 sk_sp<SkColorSpace> imageColorSpace,
82 PromiseImageTextureFulfillProc textureFulfillProc,
83 PromiseImageTextureReleaseProc textureReleaseProc,
84 PromiseImageTextureDoneProc textureDoneProc,
85 PromiseImageTextureContext textureContexts[],
86 PromiseImageApiVersion);
87
88private:
89 SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpace>);
90
91 void flattenToRGB(GrRecordingContext*) const;
92
93 // This array will usually only be sparsely populated.
94 // The actual non-null fields are dictated by the 'fYUVAIndices' indices
95 mutable GrSurfaceProxyView fViews[4];
96 int fNumViews;
97 SkYUVAIndex fYUVAIndices[4];
98 const SkYUVColorSpace fYUVColorSpace;
99 GrSurfaceOrigin fOrigin;
100 // If this is non-null then the planar data should be converted from fFromColorSpace to
101 // this->colorSpace(). Otherwise we assume the planar data (post YUV->RGB conversion) is already
102 // in this->colorSpace().
103 const sk_sp<SkColorSpace> fFromColorSpace;
104
105 // Repeated calls to onMakeColorSpace will result in a proliferation of unique IDs and
106 // SkImage_GpuYUVA instances. Cache the result of the last successful onMakeColorSpace call.
107 mutable sk_sp<SkColorSpace> fOnMakeColorSpaceTarget;
108 mutable sk_sp<SkImage> fOnMakeColorSpaceResult;
109
110 // This is only allocated when the image needs to be flattened rather than
111 // using the separate YUVA planes. From thence forth we will only use the
112 // the RGBView.
113 mutable GrSurfaceProxyView fRGBView;
114 typedef SkImage_GpuBase INHERITED;
115};
116
117#endif
118