/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkImage_GpuYUVA_DEFINED #define SkImage_GpuYUVA_DEFINED #include "GrBackendSurface.h" #include "GrContext.h" #include "SkCachedData.h" #include "SkImage_GpuBase.h" class GrTexture; struct SkYUVASizeInfo; // Wraps the 3 or 4 planes of a YUVA image for consumption by the GPU. // Initially any direct rendering will be done by passing the individual planes to a shader. // Once any method requests a flattened image (e.g., onReadPixels), the flattened RGB // proxy will be stored and used for any future rendering. class SkImage_GpuYUVA : public SkImage_GpuBase { public: friend class GrYUVAImageTextureMaker; SkImage_GpuYUVA(sk_sp<GrContext>, int width, int height, uint32_t uniqueID, SkYUVColorSpace, sk_sp<GrTextureProxy> proxies[], int numProxies, const SkYUVAIndex[4], GrSurfaceOrigin, sk_sp<SkColorSpace>); ~SkImage_GpuYUVA() override; SkImageInfo onImageInfo() const override; GrTextureProxy* peekProxy() const override { return this->asTextureProxyRef().get(); } sk_sp<GrTextureProxy> asTextureProxyRef() const override; virtual bool onIsTextureBacked() const override { return SkToBool(fProxies[0].get()); } sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, sk_sp<SkColorSpace>) const final; virtual bool isYUVA() const override { return true; } virtual bool asYUVATextureProxiesRef(sk_sp<GrTextureProxy> proxies[4], SkYUVAIndex yuvaIndices[4], SkYUVColorSpace* yuvColorSpace) const override { for (int i = 0; i < 4; ++i) { proxies[i] = fProxies[i]; yuvaIndices[i] = fYUVAIndices[i]; } *yuvColorSpace = fYUVColorSpace; return true; } bool setupMipmapsForPlanes() const; // Returns a ref-ed texture proxy with miplevels sk_sp<GrTextureProxy> asMippedTextureProxyRef() const; SkColorSpace* targetColorSpace() const { return fTargetColorSpace.get(); } /** * This is the implementation of SkDeferredDisplayListRecorder::makeYUVAPromiseTexture. */ static sk_sp<SkImage> MakePromiseYUVATexture(GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendFormat yuvaFormats[], const SkISize yuvaSizes[], const SkYUVAIndex yuvaIndices[4], int width, int height, GrSurfaceOrigin imageOrigin, sk_sp<SkColorSpace> imageColorSpace, PromiseImageTextureFulfillProc textureFulfillProc, PromiseImageTextureReleaseProc textureReleaseProc, PromiseImageTextureDoneProc textureDoneProc, PromiseImageTextureContext textureContexts[], DelayReleaseCallback delayReleaseCallback); private: SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpace>); // This array will usually only be sparsely populated. // The actual non-null fields are dictated by the 'fYUVAIndices' indices mutable sk_sp<GrTextureProxy> fProxies[4]; int fNumProxies; SkYUVAIndex fYUVAIndices[4]; const SkYUVColorSpace fYUVColorSpace; GrSurfaceOrigin fOrigin; const sk_sp<SkColorSpace> fTargetColorSpace; // Repeated calls to onMakeColorSpace will result in a proliferation of unique IDs and // SkImage_GpuYUVA instances. Cache the result of the last successful onMakeColorSpace call. mutable sk_sp<SkColorSpace> fOnMakeColorSpaceTarget; mutable sk_sp<SkImage> fOnMakeColorSpaceResult; // This is only allocated when the image needs to be flattened rather than // using the separate YUVA planes. From thence forth we will only use the // the RGBProxy. mutable sk_sp<GrTextureProxy> fRGBProxy; typedef SkImage_GpuBase INHERITED; }; #endif