Updated blur to use A8/R8 (instead of RGBA8) when available - this provides a performance gain for large blurs

http://codereview.appspot.com/5988071/



git-svn-id: http://skia.googlecode.com/svn/trunk@3647 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
robertphillips@google.com 2012-04-10 19:26:38 +00:00
Родитель 43e384bbe5
Коммит 99a5ac0b67
8 изменённых файлов: 115 добавлений и 7 удалений

Просмотреть файл

@ -274,6 +274,11 @@ public:
const GrRenderTarget* getRenderTarget() const; const GrRenderTarget* getRenderTarget() const;
GrRenderTarget* getRenderTarget(); GrRenderTarget* getRenderTarget();
/**
* Can the provided configuration act as a color render target?
*/
bool isConfigRenderable(GrPixelConfig config) const;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Platform Surfaces // Platform Surfaces

Просмотреть файл

@ -1989,6 +1989,10 @@ const GrRenderTarget* GrContext::getRenderTarget() const {
return fDrawState->getRenderTarget(); return fDrawState->getRenderTarget();
} }
bool GrContext::isConfigRenderable(GrPixelConfig config) const {
return fGpu->isConfigRenderable(config);
}
const GrMatrix& GrContext::getMatrix() const { const GrMatrix& GrContext::getMatrix() const {
return fDrawState->getViewMatrix(); return fDrawState->getViewMatrix();
} }
@ -2112,16 +2116,22 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
static_cast<float>(scaleFactorY)); static_cast<float>(scaleFactorY));
this->setClip(srcRect); this->setClip(srcRect);
GrAssert(kBGRA_8888_PM_GrPixelConfig == srcTexture->config() ||
kRGBA_8888_PM_GrPixelConfig == srcTexture->config() ||
kAlpha_8_GrPixelConfig == srcTexture->config());
const GrTextureDesc desc = { const GrTextureDesc desc = {
kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit, kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit,
SkScalarFloorToInt(srcRect.width()), SkScalarFloorToInt(srcRect.width()),
SkScalarFloorToInt(srcRect.height()), SkScalarFloorToInt(srcRect.height()),
kRGBA_8888_PM_GrPixelConfig, srcTexture->config(),
0 // samples 0 // samples
}; };
temp1->set(this, desc); temp1->set(this, desc);
if (temp2) temp2->set(this, desc); if (temp2) {
temp2->set(this, desc);
}
GrTexture* dstTexture = temp1->texture(); GrTexture* dstTexture = temp1->texture();
GrPaint paint; GrPaint paint;
@ -2160,7 +2170,9 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
convolve(fGpu, srcTexture, srcRect, kernelX, kernelWidthX, convolve(fGpu, srcTexture, srcRect, kernelX, kernelWidthX,
GrSamplerState::kX_FilterDirection); GrSamplerState::kX_FilterDirection);
SkTSwap(srcTexture, dstTexture); SkTSwap(srcTexture, dstTexture);
if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture(); if (temp2 && dstTexture == origTexture) {
dstTexture = temp2->texture();
}
} }
if (sigmaY > 0.0f) { if (sigmaY > 0.0f) {
@ -2180,7 +2192,9 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
convolve(fGpu, srcTexture, srcRect, kernelY, kernelWidthY, convolve(fGpu, srcTexture, srcRect, kernelY, kernelWidthY,
GrSamplerState::kY_FilterDirection); GrSamplerState::kY_FilterDirection);
SkTSwap(srcTexture, dstTexture); SkTSwap(srcTexture, dstTexture);
if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture(); if (temp2 && dstTexture == origTexture) {
dstTexture = temp2->texture();
}
} }
if (scaleFactorX > 1 || scaleFactorY > 1) { if (scaleFactorX > 1 || scaleFactorY > 1) {

Просмотреть файл

@ -57,6 +57,10 @@ GrGpu::GrGpu()
poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX; poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
#endif #endif
resetStats(); resetStats();
for (int i = 0; i < kGrPixelConfigCount; ++i) {
fConfigRenderSupport[i] = false;
};
} }
GrGpu::~GrGpu() { GrGpu::~GrGpu() {

Просмотреть файл

@ -333,6 +333,14 @@ public:
return fResetTimestamp; return fResetTimestamp;
} }
/**
* Can the provided configuration act as a color render target?
*/
bool isConfigRenderable(GrPixelConfig config) const {
GrAssert(kGrPixelConfigCount > config);
return fConfigRenderSupport[config];
}
protected: protected:
enum PrivateDrawStateStateBits { enum PrivateDrawStateStateBits {
kFirstBit = (GrDrawState::kLastPublicStateBit << 1), kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
@ -377,6 +385,10 @@ protected:
return fGeomPoolStateStack.back(); return fGeomPoolStateStack.back();
} }
// Derived classes need access to this so they can fill it out in their
// constructors
bool fConfigRenderSupport[kGrPixelConfigCount];
// GrDrawTarget overrides // GrDrawTarget overrides
virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout, virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
int vertexCount, int vertexCount,

Просмотреть файл

@ -788,16 +788,20 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
} }
GrPoint offset = GrPoint::Make(-srcRect.fLeft, -srcRect.fTop); GrPoint offset = GrPoint::Make(-srcRect.fLeft, -srcRect.fTop);
srcRect.offset(offset); srcRect.offset(offset);
const GrTextureDesc desc = { GrTextureDesc desc = {
kRenderTarget_GrTextureFlagBit, kRenderTarget_GrTextureFlagBit,
SkScalarCeilToInt(srcRect.width()), SkScalarCeilToInt(srcRect.width()),
SkScalarCeilToInt(srcRect.height()), SkScalarCeilToInt(srcRect.height()),
// We actually only need A8, but it often isn't supported as a // We actually only need A8, but it often isn't supported as a
// render target // render target so default to RGBA_8888
kRGBA_8888_PM_GrPixelConfig, kRGBA_8888_PM_GrPixelConfig,
0 // samples 0 // samples
}; };
if (context->isConfigRenderable(kAlpha_8_GrPixelConfig)) {
desc.fConfig = kAlpha_8_GrPixelConfig;
}
GrAutoScratchTexture pathEntry(context, desc); GrAutoScratchTexture pathEntry(context, desc);
GrTexture* pathTexture = pathEntry.texture(); GrTexture* pathTexture = pathEntry.texture();
if (NULL == pathTexture) { if (NULL == pathTexture) {

Просмотреть файл

@ -136,7 +136,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo) {
fTextureRedSupport = version >= GR_GL_VER(3,0) || fTextureRedSupport = version >= GR_GL_VER(3,0) ||
ctxInfo.hasExtension("GL_ARB_texture_rg"); ctxInfo.hasExtension("GL_ARB_texture_rg");
} else { } else {
fTextureRedSupport = ctxInfo.hasExtension("GL_ARB_texture_rg"); fTextureRedSupport = ctxInfo.hasExtension("GL_EXT_texture_rg");
} }
this->initFSAASupport(ctxInfo); this->initFSAASupport(ctxInfo);

Просмотреть файл

@ -181,6 +181,8 @@ GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo) : fGLContextInfo(ctxInfo) {
GrAssert(ctxInfo.isInitialized()); GrAssert(ctxInfo.isInitialized());
fillInConfigRenderableTable();
fPrintedCaps = false; fPrintedCaps = false;
GrGLClearErr(fGLContextInfo.interface()); GrGLClearErr(fGLContextInfo.interface());
@ -293,6 +295,71 @@ void GrGpuGL::initCaps() {
fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType(); fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType();
} }
void GrGpuGL::fillInConfigRenderableTable() {
// OpenGL < 3.0
// no support for render targets unless the GL_ARB_framebuffer_object
// extension is supported (in which case we get ALPHA, RED, RG, RGB,
// RGBA (ALPHA8, RGBA4, RGBA8) for OpenGL > 1.1). Note that we
// probably don't get R8 in this case.
// OpenGL 3.0
// base color renderable: ALPHA, RED, RG, RGB, and RGBA
// sized derivatives: ALPHA8, R8, RGBA4, RGBA8
// >= OpenGL 3.1
// base color renderable: RED, RG, RGB, and RGBA
// sized derivatives: R8, RGBA4, RGBA8
// if the GL_ARB_compatibility extension is supported then we get back
// support for GL_ALPHA and ALPHA8
// GL_EXT_bgra adds BGRA render targets to any version
// ES 2.0
// color renderable: RGBA4, RGB5_A1, RGB565
// GL_EXT_texture_rg adds support for R8 as a color render target
// GL_OES_rgb8_rgba8 and/or GL_ARM_rgba8 adds support for RGBA8
// GL_EXT_texture_format_BGRA8888 and/or GL_APPLE_texture_format_BGRA8888
// added BGRA support
if (kDesktop_GrGLBinding == this->glBinding()) {
// Post 3.0 we will get R8
// Prior to 3.0 we will get ALPHA8 (with GL_ARB_framebuffer_object)
if (this->glVersion() >= GR_GL_VER(3,0) ||
this->hasExtension("GL_ARB_framebuffer_object")) {
fConfigRenderSupport[kAlpha_8_GrPixelConfig] = true;
}
} else {
// On ES we can only hope for R8
fConfigRenderSupport[kAlpha_8_GrPixelConfig] =
this->glCaps().textureRedSupport();
}
if (kDesktop_GrGLBinding != this->glBinding()) {
// only available in ES
fConfigRenderSupport[kRGB_565_GrPixelConfig] = true;
}
// Pre 3.0, Ganesh relies on either GL_ARB_framebuffer_object or
// GL_EXT_framebuffer_object for FBO support. Both of these
// allow RGBA4 render targets so this is always supported.
fConfigRenderSupport[kRGBA_4444_GrPixelConfig] = true;
if (this->glCaps().rgba8RenderbufferSupport()) {
fConfigRenderSupport[kRGBA_8888_PM_GrPixelConfig] = true;
}
if (this->glCaps().bgraFormatSupport()) {
fConfigRenderSupport[kBGRA_8888_PM_GrPixelConfig] = true;
}
// the un-premultiplied formats just inherit the premultiplied setting
fConfigRenderSupport[kRGBA_8888_UPM_GrPixelConfig] =
fConfigRenderSupport[kRGBA_8888_PM_GrPixelConfig];
fConfigRenderSupport[kBGRA_8888_UPM_GrPixelConfig] =
fConfigRenderSupport[kBGRA_8888_PM_GrPixelConfig];
}
bool GrGpuGL::canPreserveReadWriteUnpremulPixels() { bool GrGpuGL::canPreserveReadWriteUnpremulPixels() {
if (kUnknown_CanPreserveUnpremulRoundtrip == if (kUnknown_CanPreserveUnpremulRoundtrip ==
fCanPreserveUnpremulRoundtrip) { fCanPreserveUnpremulRoundtrip) {

Просмотреть файл

@ -233,6 +233,8 @@ private:
GrGLuint texID, GrGLuint texID,
GrGLRenderTarget::Desc* desc); GrGLRenderTarget::Desc* desc);
void fillInConfigRenderableTable();
friend class GrGLVertexBuffer; friend class GrGLVertexBuffer;
friend class GrGLIndexBuffer; friend class GrGLIndexBuffer;
friend class GrGLTexture; friend class GrGLTexture;