Preparatory Proxification
This is pulled out of: https://skia-review.googlesource.com/c/8823/ (Remove GrFragmentProcessor-derived class' GrTexture-based ctors) Change-Id: I93e233cd80d98c848d79272423cb58505d72ff3e Reviewed-on: https://skia-review.googlesource.com/9559 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
f85f2a9c93
commit
b66b42f174
@ -17,6 +17,7 @@
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContext.h"
|
||||
#include "GrResourceProvider.h"
|
||||
#include "GrSurfaceContext.h"
|
||||
#include "GrSurfaceProxyPriv.h"
|
||||
#include "GrTexture.h"
|
||||
@ -474,7 +475,7 @@ public:
|
||||
if (subset) {
|
||||
// TODO: if this becomes a bottle neck we could base this logic on what the size
|
||||
// will be when it is finally instantiated - but that is more fraught.
|
||||
if (fTextureProxy->priv().isExact() &&
|
||||
if (GrResourceProvider::IsFunctionallyExact(fTextureProxy.get()) &&
|
||||
0 == subset->fLeft && 0 == subset->fTop &&
|
||||
fTextureProxy->width() == subset->width() &&
|
||||
fTextureProxy->height() == subset->height()) {
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "GrResourceKey.h"
|
||||
#include "GrSemaphore.h"
|
||||
#include "GrStencilAttachment.h"
|
||||
#include "GrSurfaceProxyPriv.h"
|
||||
#include "GrTexturePriv.h"
|
||||
#include "../private/GrSingleOwner.h"
|
||||
#include "SkMathPriv.h"
|
||||
@ -39,6 +40,9 @@ GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSin
|
||||
fQuadIndexBufferKey = gQuadIndexBufferKey;
|
||||
}
|
||||
|
||||
bool GrResourceProvider::IsFunctionallyExact(GrTextureProxy* proxy) {
|
||||
return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
|
||||
}
|
||||
|
||||
GrTexture* GrResourceProvider::createMipMappedTexture(const GrSurfaceDesc& desc,
|
||||
SkBudgeted budgeted, const GrMipLevel* texels,
|
||||
|
@ -243,6 +243,10 @@ public:
|
||||
fGpu = NULL;
|
||||
}
|
||||
|
||||
// 'Proxy' is about to be used as a texture src. This query can be used to determine if
|
||||
// it is going to need a texture domain.
|
||||
static bool IsFunctionallyExact(GrTextureProxy* proxy);
|
||||
|
||||
private:
|
||||
GrTexture* internalCreateApproxTexture(const GrSurfaceDesc& desc, uint32_t scratchTextureFlags);
|
||||
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
// future when the proxy is actually used/instantiated.
|
||||
bool hasPendingIO() const { return fProxy->hasPendingIO(); }
|
||||
|
||||
// Don't abuse this!!!!!!!
|
||||
// Don't abuse these two!!!!!!!
|
||||
bool isExact() const { return SkBackingFit::kExact == fProxy->fFit; }
|
||||
|
||||
// These next two are very specialized and wacky - don't use them!
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "GrTextureProducer.h"
|
||||
#include "GrClip.h"
|
||||
#include "GrRenderTargetContext.h"
|
||||
#include "GrResourceProvider.h"
|
||||
#include "GrSurfaceProxy.h"
|
||||
#include "GrSurfaceProxyPriv.h"
|
||||
#include "GrTexture.h"
|
||||
#include "effects/GrBicubicEffect.h"
|
||||
#include "effects/GrSimpleTextureEffect.h"
|
||||
@ -63,6 +66,64 @@ GrTexture* GrTextureProducer::CopyOnGpu(GrTexture* inputTexture, const SkIRect*
|
||||
return copyRTC->asTexture().release();
|
||||
}
|
||||
|
||||
sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context,
|
||||
sk_sp<GrTextureProxy> inputProxy,
|
||||
const SkIRect* subset,
|
||||
const CopyParams& copyParams) {
|
||||
SkASSERT(!subset || !subset->isEmpty());
|
||||
SkASSERT(context);
|
||||
|
||||
GrPixelConfig config = GrMakePixelConfigUncompressed(inputProxy->config());
|
||||
|
||||
const SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight);
|
||||
|
||||
sk_sp<GrRenderTargetContext> copyRTC = context->makeRenderTargetContextWithFallback(
|
||||
SkBackingFit::kExact, dstRect.width(), dstRect.height(), config, nullptr);
|
||||
if (!copyRTC) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrPaint paint;
|
||||
paint.setGammaCorrect(true);
|
||||
|
||||
SkRect localRect;
|
||||
if (subset) {
|
||||
localRect = SkRect::Make(*subset);
|
||||
} else {
|
||||
localRect = SkRect::MakeWH(inputProxy->width(), inputProxy->height());
|
||||
}
|
||||
|
||||
bool needsDomain = false;
|
||||
if (copyParams.fFilter != GrSamplerParams::kNone_FilterMode) {
|
||||
bool resizing = subset->width() != dstRect.width() || subset->height() != dstRect.height();
|
||||
|
||||
if (GrResourceProvider::IsFunctionallyExact(inputProxy.get())) {
|
||||
needsDomain = subset && resizing;
|
||||
} else {
|
||||
needsDomain = resizing;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsDomain) {
|
||||
const SkRect domain = localRect.makeInset(0.5f, 0.5f);
|
||||
// This would cause us to read values from outside the subset. Surely, the caller knows
|
||||
// better!
|
||||
SkASSERT(copyParams.fFilter != GrSamplerParams::kMipMap_FilterMode);
|
||||
paint.addColorFragmentProcessor(
|
||||
GrTextureDomainEffect::Make(context, std::move(inputProxy), nullptr, SkMatrix::I(),
|
||||
domain, GrTextureDomain::kClamp_Mode, copyParams.fFilter));
|
||||
} else {
|
||||
GrSamplerParams params(SkShader::kClamp_TileMode, copyParams.fFilter);
|
||||
paint.addColorTextureProcessor(context, std::move(inputProxy),
|
||||
nullptr, SkMatrix::I(), params);
|
||||
}
|
||||
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
|
||||
|
||||
copyRTC->fillRectToRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
|
||||
localRect);
|
||||
return copyRTC->asTextureProxyRef();
|
||||
}
|
||||
|
||||
/** Determines whether a texture domain is necessary and if so what domain to use. There are two
|
||||
* rectangles to consider:
|
||||
* - The first is the content area specified by the texture adjuster. We can *never* allow
|
||||
@ -233,3 +294,37 @@ sk_sp<GrFragmentProcessor> GrTextureProducer::CreateFragmentProcessorForDomainAn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<GrFragmentProcessor> GrTextureProducer::CreateFragmentProcessorForDomainAndFilter(
|
||||
GrContext* context,
|
||||
sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& textureMatrix,
|
||||
DomainMode domainMode,
|
||||
const SkRect& domain,
|
||||
const GrSamplerParams::FilterMode* filterOrNullForBicubic) {
|
||||
SkASSERT(kTightCopy_DomainMode != domainMode);
|
||||
if (filterOrNullForBicubic) {
|
||||
if (kDomain_DomainMode == domainMode) {
|
||||
return GrTextureDomainEffect::Make(context, std::move(proxy),
|
||||
std::move(colorSpaceXform), textureMatrix,
|
||||
domain, GrTextureDomain::kClamp_Mode,
|
||||
*filterOrNullForBicubic);
|
||||
} else {
|
||||
GrSamplerParams params(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
|
||||
return GrSimpleTextureEffect::Make(context, std::move(proxy),
|
||||
std::move(colorSpaceXform), textureMatrix,
|
||||
params);
|
||||
}
|
||||
} else {
|
||||
if (kDomain_DomainMode == domainMode) {
|
||||
return GrBicubicEffect::Make(context, std::move(proxy), std::move(colorSpaceXform),
|
||||
textureMatrix, domain);
|
||||
} else {
|
||||
static const SkShader::TileMode kClampClamp[] =
|
||||
{ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode };
|
||||
return GrBicubicEffect::Make(context, std::move(proxy), std::move(colorSpaceXform),
|
||||
textureMatrix, kClampClamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
class GrColorSpaceXform;
|
||||
class GrTexture;
|
||||
class GrTextureProxy;
|
||||
|
||||
/**
|
||||
* Different GPUs and API extensions have different requirements with respect to what texture
|
||||
@ -118,6 +119,9 @@ protected:
|
||||
static GrTexture* CopyOnGpu(GrTexture* inputTexture, const SkIRect* subset,
|
||||
const CopyParams& copyParams);
|
||||
|
||||
static sk_sp<GrTextureProxy> CopyOnGpu(GrContext*, sk_sp<GrTextureProxy> inputProxy,
|
||||
const SkIRect* subset, const CopyParams& copyParams);
|
||||
|
||||
static DomainMode DetermineDomainMode(
|
||||
const SkRect& constraintRect,
|
||||
FilterConstraint filterConstraint,
|
||||
@ -135,6 +139,15 @@ protected:
|
||||
const SkRect& domain,
|
||||
const GrSamplerParams::FilterMode* filterOrNullForBicubic);
|
||||
|
||||
static sk_sp<GrFragmentProcessor> CreateFragmentProcessorForDomainAndFilter(
|
||||
GrContext* context,
|
||||
sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& textureMatrix,
|
||||
DomainMode,
|
||||
const SkRect& domain,
|
||||
const GrSamplerParams::FilterMode* filterOrNullForBicubic);
|
||||
|
||||
private:
|
||||
const int fWidth;
|
||||
const int fHeight;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "GrTextureDomain.h"
|
||||
|
||||
#include "GrContext.h"
|
||||
#include "GrResourceProvider.h"
|
||||
#include "GrShaderCaps.h"
|
||||
#include "GrSimpleTextureEffect.h"
|
||||
#include "GrSurfaceProxyPriv.h"
|
||||
@ -19,8 +20,8 @@
|
||||
#include "glsl/GrGLSLShaderBuilder.h"
|
||||
#include "glsl/GrGLSLUniformHandler.h"
|
||||
|
||||
static bool can_ignore_rect(GrSurfaceProxy* proxy, const SkRect& domain) {
|
||||
if (proxy->priv().isExact()) {
|
||||
static bool can_ignore_rect(GrTextureProxy* proxy, const SkRect& domain) {
|
||||
if (GrResourceProvider::IsFunctionallyExact(proxy)) {
|
||||
const SkIRect kFullRect = SkIRect::MakeWH(proxy->width(), proxy->height());
|
||||
|
||||
return domain.contains(kFullRect);
|
||||
|
@ -646,8 +646,8 @@ private:
|
||||
// convert texcoords to unsigned short format
|
||||
sk_sp<GrTextureProxy> proxy = atlas->getProxy();
|
||||
|
||||
// The proxy must be exact for this normalization to work correctly
|
||||
SkASSERT(proxy->priv().isExact());
|
||||
// The proxy must be functionally exact for this normalization to work correctly
|
||||
SkASSERT(GrResourceProvider::IsFunctionallyExact(proxy.get()));
|
||||
SkScalar uFactor = 65535.f / proxy->width();
|
||||
SkScalar vFactor = 65535.f / proxy->height();
|
||||
uint16_t l = (uint16_t)(texLeft*uFactor);
|
||||
|
Loading…
Reference in New Issue
Block a user