aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrCoordTransform.cpp69
-rw-r--r--src/gpu/GrProcessor.cpp11
-rw-r--r--src/gpu/GrSurfaceProxy.cpp4
-rw-r--r--src/gpu/GrYUVProvider.cpp35
-rw-r--r--src/gpu/effects/GrYUVEffect.cpp41
-rw-r--r--src/gpu/effects/GrYUVEffect.h22
6 files changed, 127 insertions, 55 deletions
diff --git a/src/gpu/GrCoordTransform.cpp b/src/gpu/GrCoordTransform.cpp
index 4afd0efbce..99b3a09fc9 100644
--- a/src/gpu/GrCoordTransform.cpp
+++ b/src/gpu/GrCoordTransform.cpp
@@ -9,30 +9,23 @@
#include "GrCaps.h"
#include "GrContext.h"
#include "GrGpu.h"
+#include "GrTextureProxy.h"
-void GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
- GrSamplerParams::FilterMode filter, bool normalize) {
- SkASSERT(texture);
- SkASSERT(!fInProcessor);
-
- fMatrix = m;
- fTexture = texture;
- fNormalize = normalize;
- fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin();
-
+static GrSLPrecision compute_precision(const GrShaderCaps* caps,
+ int width, int height,
+ GrSamplerParams::FilterMode filter) {
// Always start at kDefault. Then if precisions differ we see if the precision needs to be
// increased. Our rule is that we want at least 4 subpixel values in the representation for
// coords between 0 to 1 when bi- or tri-lerping and 1 value when nearest filtering. Note that
// this still might not be enough when drawing with repeat or mirror-repeat modes but that case
// can be arbitrarily bad.
int subPixelThresh = filter > GrSamplerParams::kNone_FilterMode ? 4 : 1;
- fPrecision = kDefault_GrSLPrecision;
- if (texture->getContext()) {
- const GrShaderCaps* caps = texture->getContext()->caps()->shaderCaps();
+ GrSLPrecision precision = kDefault_GrSLPrecision;
+ if (caps) {
if (caps->floatPrecisionVaries()) {
- int maxD = SkTMax(texture->width(), texture->height());
+ int maxD = SkTMax(width, height);
const GrShaderCaps::PrecisionInfo* info;
- info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, fPrecision);
+ info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, precision);
do {
SkASSERT(info->supported());
// Make sure there is at least 2 bits of subpixel precision in the range of
@@ -40,17 +33,57 @@ void GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
if ((2 << info->fBits) / maxD > subPixelThresh) {
break;
}
- if (kHigh_GrSLPrecision == fPrecision) {
+ if (kHigh_GrSLPrecision == precision) {
break;
}
- GrSLPrecision nextP = static_cast<GrSLPrecision>(fPrecision + 1);
+ GrSLPrecision nextP = static_cast<GrSLPrecision>(precision + 1);
info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, nextP);
if (!info->supported()) {
break;
}
- fPrecision = nextP;
+ precision = nextP;
} while (true);
}
}
+
+ return precision;
+}
+
+void GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
+ GrSamplerParams::FilterMode filter, bool normalize) {
+ SkASSERT(texture);
+ SkASSERT(!fInProcessor);
+
+ fMatrix = m;
+ fTexture = texture;
+ fNormalize = normalize;
+ fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin();
+
+ if (texture->getContext()) {
+ fPrecision = compute_precision(texture->getContext()->caps()->shaderCaps(),
+ texture->width(), texture->height(), filter);
+ } else {
+ fPrecision = kDefault_GrSLPrecision;
+ }
+}
+
+void GrCoordTransform::reset(GrContext* context, const SkMatrix& m,
+ GrTextureProxy* proxy,
+ GrSamplerParams::FilterMode filter, bool normalize) {
+ SkASSERT(proxy);
+ SkASSERT(!fInProcessor);
+
+ fMatrix = m;
+ // MDB TODO: just GrCaps is needed for this method
+ // MDB TODO: once all the coord transforms take a proxy just store it here and
+ // instantiate later
+ fTexture = proxy->instantiate(context->textureProvider());
+ fNormalize = normalize;
+ fReverseY = kBottomLeft_GrSurfaceOrigin == proxy->origin();
+
+ const GrCaps* caps = context->caps();
+ fPrecision = compute_precision(caps->shaderCaps(),
+ proxy->worstCaseWidth(*caps),
+ proxy->worstCaseHeight(*caps), filter);
}
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index f4bead2d08..3e1346482f 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -12,6 +12,7 @@
#include "GrMemoryPool.h"
#include "GrSamplerParams.h"
#include "GrTexturePriv.h"
+#include "GrTextureProxy.h"
#include "GrXferProcessor.h"
#include "SkSpinlock.h"
@@ -207,6 +208,16 @@ GrProcessor::TextureSampler::TextureSampler(GrTexture* texture,
this->reset(texture, filterMode, tileXAndY, visibility);
}
+GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider,
+ sk_sp<GrTextureProxy> proxy,
+ GrSamplerParams::FilterMode filterMode,
+ SkShader::TileMode tileXAndY,
+ GrShaderFlags visibility) {
+ // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
+ // to taking a GrSurfaceProxy just use the IORefs on the proxy
+ this->reset( proxy->instantiate(texProvider), filterMode, tileXAndY, visibility);
+}
+
void GrProcessor::TextureSampler::reset(GrTexture* texture,
const GrSamplerParams& params,
GrShaderFlags visibility) {
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 780ff8aa44..48fc401b4e 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -113,6 +113,10 @@ GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
}
sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf) {
+ if (!surf) {
+ return nullptr;
+ }
+
if (surf->asTexture()) {
if (surf->asRenderTarget()) {
return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(std::move(surf)));
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 2f75d92b46..f3231a49da 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -6,7 +6,9 @@
*/
#include "GrContext.h"
+#include "GrContextPriv.h"
#include "GrRenderTargetContext.h"
+#include "GrTextureProxy.h"
#include "GrYUVProvider.h"
#include "effects/GrGammaEffect.h"
#include "effects/GrYUVEffect.h"
@@ -93,25 +95,29 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
}
GrSurfaceDesc yuvDesc;
+ yuvDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
- sk_sp<GrTexture> yuvTextures[3];
+ sk_sp<GrSurfaceContext> yuvTextureContexts[3];
for (int i = 0; i < 3; i++) {
yuvDesc.fWidth = yuvInfo.fSizeInfo.fSizes[i].fWidth;
yuvDesc.fHeight = yuvInfo.fSizeInfo.fSizes[i].fHeight;
// TODO: why do we need this check?
- bool needsExactTexture =
+ SkBackingFit fit =
(yuvDesc.fWidth != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth) ||
- (yuvDesc.fHeight != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
- if (needsExactTexture) {
- yuvTextures[i].reset(ctx->textureProvider()->createTexture(yuvDesc, SkBudgeted::kYes));
- } else {
- yuvTextures[i].reset(ctx->textureProvider()->createApproxTexture(yuvDesc));
+ (yuvDesc.fHeight != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight)
+ ? SkBackingFit::kExact : SkBackingFit::kApprox;
+
+ yuvTextureContexts[i] = ctx->contextPriv().makeDeferredSurfaceContext(yuvDesc, fit,
+ SkBudgeted::kYes);
+ if (!yuvTextureContexts[i]) {
+ return nullptr;
+ }
+
+ const SkImageInfo ii = SkImageInfo::MakeA8(yuvDesc.fWidth, yuvDesc.fHeight);
+ if (!yuvTextureContexts[i]->writePixels(ii, planes[i],
+ yuvInfo.fSizeInfo.fWidthBytes[i], 0, 0)) {
+ return nullptr;
}
- if (!yuvTextures[i] ||
- !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, yuvDesc.fConfig,
- planes[i], yuvInfo.fSizeInfo.fWidthBytes[i])) {
- return nullptr;
- }
}
// We never want to perform color-space conversion during the decode
@@ -126,7 +132,10 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
GrPaint paint;
sk_sp<GrFragmentProcessor> yuvToRgbProcessor(
- GrYUVEffect::MakeYUVToRGB(yuvTextures[0].get(), yuvTextures[1].get(), yuvTextures[2].get(),
+ GrYUVEffect::MakeYUVToRGB(ctx,
+ sk_ref_sp(yuvTextureContexts[0]->asDeferredTexture()),
+ sk_ref_sp(yuvTextureContexts[1]->asDeferredTexture()),
+ sk_ref_sp(yuvTextureContexts[2]->asDeferredTexture()),
yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false));
paint.addColorFragmentProcessor(std::move(yuvToRgbProcessor));
diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp
index 6b15c0dc72..254cdffd2b 100644
--- a/src/gpu/effects/GrYUVEffect.cpp
+++ b/src/gpu/effects/GrYUVEffect.cpp
@@ -7,10 +7,12 @@
#include "GrYUVEffect.h"
+#include "GrContext.h"
#include "GrCoordTransform.h"
#include "GrFragmentProcessor.h"
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
+#include "GrTextureProxy.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
@@ -62,8 +64,10 @@ static const float kRec709InverseConversionMatrix[16] = {
class YUVtoRGBEffect : public GrFragmentProcessor {
public:
- static sk_sp<GrFragmentProcessor> Make(GrTexture* yTexture, GrTexture* uTexture,
- GrTexture* vTexture, const SkISize sizes[3],
+ static sk_sp<GrFragmentProcessor> Make(GrContext* context,
+ sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy, const SkISize sizes[3],
SkYUVColorSpace colorSpace, bool nv12) {
SkScalar w[3], h[3];
w[0] = SkIntToScalar(sizes[0].fWidth);
@@ -85,7 +89,8 @@ public:
GrSamplerParams::kBilerp_FilterMode :
GrSamplerParams::kNone_FilterMode;
return sk_sp<GrFragmentProcessor>(new YUVtoRGBEffect(
- yTexture, uTexture, vTexture, yuvMatrix, uvFilterMode, colorSpace, nv12));
+ context, std::move(yProxy), std::move(uProxy), std::move(vProxy),
+ yuvMatrix, uvFilterMode, colorSpace, nv12));
}
const char* name() const override { return "YUV to RGB"; }
@@ -150,14 +155,17 @@ public:
};
private:
- YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+ YUVtoRGBEffect(GrContext* ctx,
+ sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy,
const SkMatrix yuvMatrix[3], GrSamplerParams::FilterMode uvFilterMode,
SkYUVColorSpace colorSpace, bool nv12)
- : fYTransform(yuvMatrix[0], yTexture, GrSamplerParams::kNone_FilterMode)
- , fYSampler(yTexture)
- , fUTransform(yuvMatrix[1], uTexture, uvFilterMode)
- , fUSampler(uTexture, uvFilterMode)
- , fVSampler(vTexture, uvFilterMode)
+ : fYTransform(ctx, yuvMatrix[0], yProxy.get(), GrSamplerParams::kNone_FilterMode)
+ , fYSampler(ctx->textureProvider(), std::move(yProxy))
+ , fUTransform(ctx, yuvMatrix[1], uProxy.get(), uvFilterMode)
+ , fUSampler(ctx->textureProvider(), std::move(uProxy), uvFilterMode)
+ , fVSampler(ctx->textureProvider(), vProxy, uvFilterMode)
, fColorSpace(colorSpace)
, fNV12(nv12) {
this->initClassID<YUVtoRGBEffect>();
@@ -166,7 +174,7 @@ private:
this->addCoordTransform(&fUTransform);
this->addTextureSampler(&fUSampler);
if (!fNV12) {
- fVTransform = GrCoordTransform(yuvMatrix[2], vTexture, uvFilterMode);
+ fVTransform = GrCoordTransform(ctx, yuvMatrix[2], vProxy.get(), uvFilterMode);
this->addCoordTransform(&fVTransform);
this->addTextureSampler(&fVSampler);
}
@@ -362,11 +370,16 @@ private:
//////////////////////////////////////////////////////////////////////////////
-sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture,
- GrTexture* vTexture, const SkISize sizes[3],
+sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrContext* context,
+ sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy,
+ const SkISize sizes[3],
SkYUVColorSpace colorSpace, bool nv12) {
- SkASSERT(yTexture && uTexture && vTexture && sizes);
- return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace, nv12);
+ SkASSERT(yProxy && uProxy && vProxy && sizes);
+ return YUVtoRGBEffect::Make(context,
+ std::move(yProxy), std::move(uProxy), std::move(vProxy),
+ sizes, colorSpace, nv12);
}
sk_sp<GrFragmentProcessor>
diff --git a/src/gpu/effects/GrYUVEffect.h b/src/gpu/effects/GrYUVEffect.h
index 902a181fd4..6af442ea9a 100644
--- a/src/gpu/effects/GrYUVEffect.h
+++ b/src/gpu/effects/GrYUVEffect.h
@@ -10,16 +10,20 @@
#include "SkImageInfo.h"
+class GrContext;
class GrFragmentProcessor;
-class GrTexture;
+class GrTextureProvider;
+class GrTextureProxy;
namespace GrYUVEffect {
/**
* Creates an effect that performs color conversion from YUV to RGB. The input textures are
* assumed to be kA8_GrPixelConfig.
*/
- sk_sp<GrFragmentProcessor> MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture,
- GrTexture* vTexture, const SkISize sizes[3],
+ sk_sp<GrFragmentProcessor> MakeYUVToRGB(GrContext* context,
+ sk_sp<GrTextureProxy> yProxy,
+ sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy, const SkISize sizes[3],
SkYUVColorSpace colorSpace, bool nv12);
/**
@@ -27,24 +31,22 @@ namespace GrYUVEffect {
* channels to Y, U ,and V channels. The output color is (y, u, v, a) where a is the passed in
* processor's alpha output.
*/
- sk_sp<GrFragmentProcessor> MakeRGBToYUV(sk_sp<GrFragmentProcessor>,
- SkYUVColorSpace colorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToYUV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
/**
* Creates a processor that performs color conversion from the passed in processor's RGB
* channels to U and V channels. The output color is (u, v, 0, a) where a is the passed in
* processor's alpha output.
*/
- sk_sp<GrFragmentProcessor> MakeRGBToUV(sk_sp<GrFragmentProcessor>,
- SkYUVColorSpace colorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToUV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
/**
* Creates a processor that performs color conversion from the passed in fragment processors's
* RGB channels to Y, U, or V (replicated across all four output color channels). The alpha
* output of the passed in fragment processor is ignored.
*/
- sk_sp<GrFragmentProcessor> MakeRGBToY(sk_sp<GrFragmentProcessor>, SkYUVColorSpace colorSpace);
- sk_sp<GrFragmentProcessor> MakeRGBToU(sk_sp<GrFragmentProcessor>, SkYUVColorSpace colorSpace);
- sk_sp<GrFragmentProcessor> MakeRGBToV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace colorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToY(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToU(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
+ sk_sp<GrFragmentProcessor> MakeRGBToV(sk_sp<GrFragmentProcessor>, SkYUVColorSpace);
};
#endif