Add code path for Gr client to resolve an Gr-created MSAA render target.

Review URL: http://codereview.appspot.com/5580049/


git-svn-id: http://skia.googlecode.com/svn/trunk@3112 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-01-31 13:35:56 +00:00
Родитель 75942098c5
Коммит 75f9f25d8b
9 изменённых файлов: 66 добавлений и 6 удалений

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

@ -562,6 +562,20 @@ public:
* @param dst the render target to copy to.
*/
void copyTexture(GrTexture* src, GrRenderTarget* dst);
/**
* Resolves a render target that has MSAA. The intermediate MSAA buffer is
* downsampled to the associated GrTexture (accessible via
* GrRenderTarget::asTexture()). Any pending draws to the render target will
* be executed before the resolve.
*
* This is only necessary when a client wants to access the object directly
* using the underlying graphics API. GrContext will detect when it must
* perform a resolve to a GrTexture used as the source of a draw or before
* reading pixels back from a GrTexture or GrRenderTarget.
*/
void resolveRenderTarget(GrRenderTarget* target);
/**
* Applies a 1D convolution kernel in the X direction to a rectangle of
* pixels from a given texture.

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

@ -112,6 +112,14 @@ public:
*/
const GrIRect& getResolveRect() const { return fResolveRect; }
/**
* If the render target is multisampled this will perform a multisample
* resolve. Any pending draws to the target are first flushed. This only
* applies to render targets that are associated with GrTextures. After the
* function returns the GrTexture will contain the resolved pixels.
*/
void resolve();
// GrResource overrides
virtual size_t sizeInBytes() const;

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

@ -1900,6 +1900,16 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
config, buffer, rowBytes, flipY);
}
void GrContext::resolveRenderTarget(GrRenderTarget* target) {
GrAssert(target);
ASSERT_OWNED_RESOURCE(target);
// In the future we may track whether there are any pending draws to this
// target. We don't today so we always perform a flush. We don't promise
// this to our clients, though.
this->flush();
fGpu->resolveRenderTarget(target);
}
void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
if (NULL == src || NULL == dst) {
return;

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

@ -260,6 +260,13 @@ void GrGpu::writeTexturePixels(GrTexture* texture,
config, buffer, rowBytes);
}
void GrGpu::resolveRenderTarget(GrRenderTarget* target) {
GrAssert(target);
this->handleDirtyContext();
this->onResolveRenderTarget(target);
}
////////////////////////////////////////////////////////////////////////////////
static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;

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

@ -171,6 +171,11 @@ public:
*/
const GrVertexBuffer* getUnitSquareVertexBuffer() const;
/**
* Resolves MSAA.
*/
void resolveRenderTarget(GrRenderTarget* target);
/**
* Ensures that the current render target is actually set in the
* underlying 3D API. Used when client wants to use 3D API to directly
@ -433,6 +438,9 @@ protected:
GrPixelConfig config, const void* buffer,
size_t rowBytes) = 0;
// overridden by API-specific derived class to perform the resolve
virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;
// called to program the vertex data, indexCount will be 0 if drawing non-
// indexed geometry. The subclass may adjust the startVertex and/or
// startIndex since it may have already accounted for these in the setup.

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

@ -1452,7 +1452,7 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
this->flushRenderTarget(&GrIRect::EmptyIRect());
break;
case GrGLRenderTarget::kCanResolve_ResolveType:
this->resolveRenderTarget(tgt);
this->onResolveRenderTarget(tgt);
// we don't track the state of the READ FBO ID.
GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
tgt->textureFBOID()));
@ -1666,7 +1666,9 @@ void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
#endif
}
void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) {
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
if (rt->needsResolve()) {
GrAssert(GLCaps::kNone_MSFBO != fGLCaps.fMSFBOType);
@ -2050,7 +2052,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
GrGLRenderTarget* texRT =
static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
if (NULL != texRT) {
resolveRenderTarget(texRT);
this->onResolveRenderTarget(texRT);
}
if (fHWDrawState.getTexture(s) != nextTexture) {

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

@ -41,6 +41,7 @@ public:
GrPixelConfig config,
size_t rowBytes) const SK_OVERRIDE;
virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
protected:
GrGpuGL(const GrGLInterface* glInterface, GrGLBinding glBinding);
@ -193,6 +194,9 @@ protected:
GrPixelConfig config, const void* buffer,
size_t rowBytes) SK_OVERRIDE;
virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
virtual void onGpuDrawIndexed(GrPrimitiveType type,
uint32_t startVertex,
uint32_t startIndex,
@ -276,8 +280,6 @@ private:
void flushStencil();
void flushAAState(GrPrimitiveType type);
void resolveRenderTarget(GrGLRenderTarget* texture);
bool configToGLFormats(GrPixelConfig config,
bool getSizedInternal,
GrGLenum* internalFormat,

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

@ -41,6 +41,15 @@ void GrRenderTarget::writePixels(int left, int top, int width, int height,
config, buffer, rowBytes);
}
void GrRenderTarget::resolve() {
// go through context so that all necessary flushing occurs
GrContext* context = this->getContext();
if (NULL == context) {
return;
}
context->resolveRenderTarget(this);
}
size_t GrRenderTarget::sizeInBytes() const {
int colorBits;
if (kUnknown_GrPixelConfig == fConfig) {

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

@ -1769,7 +1769,7 @@ bool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
}
void SkGpuDevice::flush() {
fContext->flush(false);
fContext->resolveRenderTarget(fRenderTarget);
}
///////////////////////////////////////////////////////////////////////////////