int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
int maxTextureSize() const { return fMaxTextureSize; }
- /** 0 unless GPU has problems with small textures */
- int minTextureSize() const { return fMinTextureSize; }
// Will be 0 if MSAA is not supported
int maxSampleCount() const { return fMaxSampleCount; }
int fMaxRenderTargetSize;
int fMaxTextureSize;
- int fMinTextureSize;
int fMaxSampleCount;
// The first entry for each config is without msaa and the second is with.
: fDrawPathToCompressedTexture(false)
, fSuppressPrints(false)
, fMaxTextureSizeOverride(SK_MaxS32)
- , fMinTextureSizeOverride(0)
, fSuppressDualSourceBlending(false)
, fGeometryBufferMapThreshold(-1)
, fUseDrawInsteadOfPartialRenderTargetWrite(false)
detected values. */
int fMaxTextureSizeOverride;
- int fMinTextureSizeOverride;
bool fSuppressDualSourceBlending;
/** the threshold in bytes above which we will use a buffer mapping API to map vertex and index
}
protected:
- GrTexture* peekOriginalTexture() override { return nullptr; }
-
// TODO: consider overriding this, for the case where the underlying generator might be
// able to efficiently produce a "stretched" texture natively (e.g. picture-backed)
// GrTexture* generateTextureForParams(GrContext*, const SkGrStretch&) override;
}
}
- bool getROBitmap(SkBitmap* bitmap) override {
- return fCacher->lockAsBitmap(bitmap, fClient);
- }
-
private:
SkImageCacherator* fCacher;
const SkImage* fClient;
fMaxRenderTargetSize = 1;
fMaxTextureSize = 1;
- fMinTextureSize = 1;
fMaxSampleCount = 0;
memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride);
- fMinTextureSize = SkTMax(fMinTextureSize, options.fMinTextureSizeOverride);
}
static SkString map_flags_to_string(uint32_t flags) {
}
r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
- r.appendf("Min Texture Size : %d\n", fMinTextureSize);
r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
r.appendf("Max Sample Count : %d\n", fMaxSampleCount);
bool GrGpu::makeCopyForTextureParams(int width, int height, const GrTextureParams& textureParams,
GrTextureParamsAdjuster::CopyParams* copyParams) const {
- bool doCopy = false;
const GrCaps& caps = *this->caps();
if (textureParams.isTiled() && !caps.npotTextureTileSupport() &&
(!SkIsPow2(width) || !SkIsPow2(height))) {
- doCopy = true;
- copyParams->fWidth = GrNextPow2(SkTMax(width, caps.minTextureSize()));
- copyParams->fHeight = GrNextPow2(SkTMax(height, caps.minTextureSize()));
- } else if (width < caps.minTextureSize() || height < caps.minTextureSize()) {
- // The small texture issues appear to be with tiling. Hence it seems ok to scale
- // them up using the GPU. If issues persist we may need to CPU-stretch.
- doCopy = true;
- copyParams->fWidth = SkTMax(width, caps.minTextureSize());
- copyParams->fHeight = SkTMax(height, caps.minTextureSize());
- }
- if (doCopy) {
+ copyParams->fWidth = GrNextPow2(width);
+ copyParams->fHeight = GrNextPow2(height);
switch (textureParams.filterMode()) {
case GrTextureParams::kNone_FilterMode:
copyParams->fFilter = GrTextureParams::kNone_FilterMode;
copyParams->fFilter = GrTextureParams::kBilerp_FilterMode;
break;
}
+ return true;
}
- return doCopy;
+ return false;
}
static GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin, bool renderTarget) {
return copy.detach();
}
-static SkBitmap copy_on_cpu(const SkBitmap& bmp, const CopyParams& copyParams) {
- SkBitmap stretched;
- stretched.allocN32Pixels(copyParams.fWidth, copyParams.fHeight);
- SkCanvas canvas(stretched);
- SkPaint paint;
- switch (copyParams.fFilter) {
- case GrTextureParams::kNone_FilterMode:
- paint.setFilterQuality(kNone_SkFilterQuality);
- break;
- case GrTextureParams::kBilerp_FilterMode:
- paint.setFilterQuality(kLow_SkFilterQuality);
- break;
- case GrTextureParams::kMipMap_FilterMode:
- paint.setFilterQuality(kMedium_SkFilterQuality);
- break;
- }
- SkRect dstRect = SkRect::MakeWH(SkIntToScalar(copyParams.fWidth),
- SkIntToScalar(copyParams.fHeight));
- canvas.drawBitmapRect(bmp, dstRect, &paint);
- return stretched;
-}
-
GrTexture* GrTextureParamsAdjuster::refTextureForParams(GrContext* ctx,
const GrTextureParams& params) {
CopyParams copyParams;
GrTexture* GrTextureParamsAdjuster::generateTextureForParams(GrContext* ctx,
const CopyParams& copyParams) {
- if ((this->width() < ctx->caps()->minTextureSize() ||
- this->height() < ctx->caps()->minTextureSize()) && !this->peekOriginalTexture())
- {
- // we can't trust our ability to use HW to perform the stretch, so we request
- // a raster instead, and perform the stretch on the CPU.
- SkBitmap bitmap;
- if (!this->getROBitmap(&bitmap)) {
- return nullptr;
- }
- SkBitmap stretchedBmp = copy_on_cpu(bitmap, copyParams);
- return GrUploadBitmapToTexture(ctx, stretchedBmp);
- } else {
- SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx));
- if (!original) {
- return nullptr;
- }
- return copy_on_gpu(original, copyParams);
+ SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx));
+ if (!original) {
+ return nullptr;
}
+ return copy_on_gpu(original, copyParams);
}
GrTexture* refTextureForParams(GrContext*, const GrTextureParams&);
protected:
- /** If the original is a inherently texture that can be returned for "free" then return it
- without ref'ing it. Otherwise, return null. */
- virtual GrTexture* peekOriginalTexture() = 0;
-
/**
* Return the maker's "original" texture. It is the responsibility of the maker
* to make this efficient ... if the texture is being generated, the maker must handle
* Return a new (uncached) texture that is the stretch of the maker's original.
*
* The base-class handles general logic for this, and only needs access to the following
- * methods:
- * - onRefOriginalTexture()
- * - onGetROBitmap()
+ * method:
+ * - refOriginalTexture()
*
* Subclass may override this if they can handle creating the texture more directly than
* by copying.
*/
virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
- /**
- * Some GPUs are unreliable w/ very small texture sizes. If we run into that case, this
- * method will be called (in service of onGenerateParamsTexture) to return a raster version
- * of the original texture.
- */
- virtual bool getROBitmap(SkBitmap*) = 0;
-
/** Helper for creating a key for a copy from an original key. */
static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
const CopyParams& copyParams,
if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
if (!(kExact_ScratchTextureFlag & flags)) {
// bin by pow2 with a reasonable min
- const int minSize = SkTMin(16, fGpu->caps()->minTextureSize());
+ const int kMinSize = 16;
GrSurfaceDesc* wdesc = desc.writable();
- wdesc->fWidth = SkTMax(minSize, GrNextPow2(desc->fWidth));
- wdesc->fHeight = SkTMax(minSize, GrNextPow2(desc->fHeight));
+ wdesc->fWidth = SkTMax(kMinSize, GrNextPow2(desc->fWidth));
+ wdesc->fHeight = SkTMax(kMinSize, GrNextPow2(desc->fHeight));
}
GrScratchKey key;
GrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bmp) {
SkASSERT(!bmp.getTexture());
- if (bmp.width() < ctx->caps()->minTextureSize() ||
- bmp.height() < ctx->caps()->minTextureSize()) {
- return nullptr;
- }
-
SkBitmap tmpBitmap;
const SkBitmap* bitmap = &bmp;
}
protected:
- GrTexture* peekOriginalTexture() override { return fBitmap.getTexture(); }
-
GrTexture* refOriginalTexture(GrContext* ctx) override {
GrTexture* tex = fBitmap.getTexture();
if (tex) {
InstallInvalidator(copyKey, fBitmap.pixelRef());
}
- bool getROBitmap(SkBitmap* bitmap) override {
- SkASSERT(!fBitmap.getTexture());
- *bitmap = fBitmap;
- return true;
- }
-
private:
static void InstallInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
class Invalidator : public SkPixelRef::GenIDChangeListener {
// attachment, hence this min:
fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
- // This GPU seems to have problems when tiling small textures
- if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
- fMinTextureSize = 16;
- }
-
fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
// Disable scratch texture reuse on Mali and Adreno devices
}
int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
- int size = this->caps()->minTextureSize();
+ static const int kSize = 16;
if (kUnknownStencilIndex == fPixelConfigToStencilIndex[config]) {
// Default to unsupported
fPixelConfigToStencilIndex[config] = kUnsupportedStencilIndex;
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D,
0, internalFormat,
- size,
- size,
+ kSize,
+ kSize,
0,
externalFormat,
externalType,
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
sFmt.fInternalFormat,
- size, size));
+ kSize, kSize));
if (GR_GL_NO_ERROR == GR_GL_GET_ERROR(this->glInterface())) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_STENCIL_ATTACHMENT,
}
// If the read is really small or smaller than the min texture size, don't force a draw.
- int minSize = SkTMax(32, caps.minTextureSize());
- if (width < minSize || height < minSize) {
+ static const int kMinSize = 32;
+ if (width < kMinSize || height < kMinSize) {
return false;
}
tempDrawInfo->fTempSurfaceDesc.fHeight = height;
tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
- tempDrawInfo->fUseExactScratch = this->glCaps().partialFBOReadIsSlow() &&
- width >= this->caps()->minTextureSize() &&
- height >= this->caps()->minTextureSize();
+ tempDrawInfo->fUseExactScratch = this->glCaps().partialFBOReadIsSlow();
// Start off assuming that any temp draw should be to the readConfig, then check if that will
// be inefficient.
{}
protected:
- GrTexture* peekOriginalTexture() override { return fOriginal; }
-
GrTexture* refOriginalTexture(GrContext* ctx) override {
return SkRef(fOriginal);
}
as_IB(fImage)->notifyAddedToCache();
}
- bool getROBitmap(SkBitmap* bitmap) override {
- return as_IB(fImage)->getROPixels(bitmap);
- }
-
private:
const SkImage* fImage;
GrTexture* fOriginal;