blob: e5a446931720b329d9f4828ebb48142753259db4 [file] [log] [blame]
/*
* 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>, SkBudgeted);
~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()); }
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;
/**
Create a new SkImage_GpuYUVA that's very similar to SkImage created by MakeFromYUVATextures.
The main difference is that the client doesn't have the backend textures on the gpu yet but
they know all the properties of the texture. So instead of passing in GrBackendTextures the
client supplies GrBackendFormats and the image size.
When we actually send the draw calls to the GPU, we will call the textureFulfillProc and
the client will return the GrBackendTextures to us. The properties of the GrBackendTextures
must match those set during the SkImage creation, and it must have valid backend gpu
textures. The gpu textures supplied by the client must stay valid until we call the
textureReleaseProc.
When we are done with the texture returned by the textureFulfillProc we will call the
textureReleaseProc passing in the textureContext. This is a signal to the client that they
are free to delete the underlying gpu textures. If future draws also use the same promise
image we will call the textureFulfillProc again if we've already called the
textureReleaseProc. We will always call textureFulfillProc and textureReleaseProc in pairs.
In other words we will never call textureFulfillProc or textureReleaseProc multiple times
for the same textureContext before calling the other.
We call the promiseDoneProc when we will no longer call the textureFulfillProc again. We
also guarantee that there will be no outstanding textureReleaseProcs that still need to be
called when we call the textureDoneProc. Thus when the textureDoneProc gets called the
client is able to cleanup all GPU objects and meta data needed for the textureFulfill call.
@param context Gpu context
@param yuvColorSpace color range of expected YUV pixels
@param yuvaFormats formats of promised gpu textures for each YUVA plane
@param yuvaSizes width and height of promised gpu textures
@param yuvaIndices mapping from yuv plane index to texture representing that plane
@param width width of promised gpu texture
@param height height of promised gpu texture
@param imageOrigin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
@param imageColorSpace range of colors; may be nullptr
@param textureFulfillProc function called to get actual gpu texture
@param textureReleaseProc function called when texture can be released
@param promiseDoneProc function called when we will no longer call textureFulfillProc
@param textureContext state passed to textureFulfillProc and textureReleaseProc
@return created SkImage, or nullptr
*/
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,
TextureFulfillProc textureFulfillProc,
TextureReleaseProc textureReleaseProc,
PromiseDoneProc promiseDoneProc,
TextureContext textureContexts[]);
private:
// 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;
// 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