blob: 1733dc13807ae0f2c19b3ca85d370e61322a66a9 [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_GpuBase_DEFINED
#define SkImage_GpuBase_DEFINED
#include "GrBackendSurface.h"
#include "GrTypesPriv.h"
#include "SkImage_Base.h"
#include "SkYUVAIndex.h"
class GrContext;
class SkColorSpace;
class SkImage_GpuBase : public SkImage_Base {
public:
SkImage_GpuBase(sk_sp<GrContext>, int width, int height, uint32_t uniqueID,
SkAlphaType, SkBudgeted, sk_sp<SkColorSpace>);
~SkImage_GpuBase() override;
GrContext* context() const final { return fContext.get(); }
bool getROPixels(SkBitmap*, CachingHint) const final;
sk_sp<SkImage> onMakeSubset(const SkIRect& subset) const final;
bool onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
int srcX, int srcY, CachingHint) const override;
sk_sp<GrTextureProxy> asTextureProxyRef() const override {
// we shouldn't end up calling this
SkASSERT(false);
return this->INHERITED::asTextureProxyRef();
}
sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerState&,
SkScalar scaleAdjust[2]) const final;
sk_sp<GrTextureProxy> refPinnedTextureProxy(uint32_t* uniqueID) const final {
*uniqueID = this->uniqueID();
return this->asTextureProxyRef();
}
GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin) const final;
GrTexture* onGetTexture() const final;
sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const final;
bool onIsValid(GrContext*) const final;
#if GR_TEST_UTILS
void resetContext(sk_sp<GrContext> newContext) {
SkASSERT(fContext->uniqueID() == newContext->uniqueID());
fContext = newContext;
}
#endif
static bool ValidateBackendTexture(GrContext* ctx, const GrBackendTexture& tex,
GrPixelConfig* config, SkColorType ct, SkAlphaType at,
sk_sp<SkColorSpace> cs);
static bool MakeTempTextureProxies(GrContext* ctx, const GrBackendTexture yuvaTextures[],
int numTextures, const SkYUVAIndex [4],
GrSurfaceOrigin imageOrigin,
sk_sp<GrTextureProxy> tempTextureProxies[4]);
static SkAlphaType GetAlphaTypeFromYUVAIndices(const SkYUVAIndex yuvaIndices[4]) {
return -1 != yuvaIndices[SkYUVAIndex::kA_Index].fIndex ? kPremul_SkAlphaType
: kOpaque_SkAlphaType;
}
typedef ReleaseContext TextureContext;
typedef void(*TextureFulfillProc)(TextureContext textureContext, GrBackendTexture* outTexture);
typedef void(*PromiseDoneProc)(TextureContext textureContext);
protected:
// Helper for making a lazy proxy for a promise image. The PromiseDoneProc we be called,
// if not null, immediately if this function fails. Othwerwise, it is installed in the
// proxy along with the TextureFulfillProc and TextureReleaseProc. PromiseDoneProc must not
// be null.
static sk_sp<GrTextureProxy> MakePromiseImageLazyProxy(
GrContext*, int width, int height, GrSurfaceOrigin, GrPixelConfig, GrBackendFormat,
GrMipMapped, SkImage_GpuBase::TextureFulfillProc, SkImage_GpuBase::TextureReleaseProc,
SkImage_GpuBase::PromiseDoneProc, SkImage_GpuBase::TextureContext);
static bool RenderYUVAToRGBA(GrContext* ctx, GrRenderTargetContext* renderTargetContext,
const SkRect& rect, SkYUVColorSpace yuvColorSpace,
const sk_sp<GrTextureProxy> proxies[4],
const SkYUVAIndex yuvaIndices[4]);
sk_sp<GrContext> fContext;
const SkAlphaType fAlphaType; // alpha type for final image
const SkBudgeted fBudgeted;
sk_sp<SkColorSpace> fColorSpace; // color space for final image
private:
typedef SkImage_Base INHERITED;
};
/**
* This helper holds the normal hard ref for the Release proc as well as a hard ref on the DoneProc.
* Thus when a GrTexture is being released, it will unref both the ReleaseProc and DoneProc.
*/
class SkPromiseReleaseProcHelper : public GrReleaseProcHelper {
public:
SkPromiseReleaseProcHelper(SkImage_GpuBase::TextureReleaseProc releaseProc,
SkImage_GpuBase::TextureContext context,
sk_sp<GrReleaseProcHelper> doneHelper)
: INHERITED(releaseProc, context)
, fDoneProcHelper(std::move(doneHelper)) {
}
void weak_dispose() const override {
// Call the inherited weak_dispose first so that we call the ReleaseProc before the DoneProc
// if we hold the last ref to the DoneProc.
INHERITED::weak_dispose();
fDoneProcHelper.reset();
}
private:
mutable sk_sp<GrReleaseProcHelper> fDoneProcHelper;
typedef GrReleaseProcHelper INHERITED;
};
#endif