Recommit r2611 with fix for gm
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 7 Nov 2011 13:29:52 +0000 (13:29 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 7 Nov 2011 13:29:52 +0000 (13:29 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@2614 2bbb7eff-a529-9590-31e7-b0007b416f81

bench/benchmain.cpp
gm/gmmain.cpp
include/gpu/GrContext.h
include/gpu/GrTypes.h
samplecode/SampleApp.cpp
src/gpu/GrContext.cpp
src/gpu/GrGLRenderTarget.h
src/gpu/GrGpu.cpp
src/gpu/GrGpu.h
src/gpu/GrGpuGL.cpp
src/gpu/GrGpuGL.h

index c58d5b1..b809c99 100644 (file)
@@ -464,15 +464,13 @@ int main (int argc, char * const argv[]) {
             reinterpret_cast<GrPlatform3DContext>(glctx.get()->gl());
         context = GrContext::Create(kOpenGL_Shaders_GrEngine, ctx);
         if (NULL != context) {
-            GrPlatformSurfaceDesc desc;
-            desc.reset();
+            GrPlatformRenderTargetDesc desc;
             desc.fConfig = kRGBA_8888_GrPixelConfig;
             desc.fWidth = contextWidth;
             desc.fHeight = contextHeight;
             desc.fStencilBits = 8;
-            desc.fPlatformRenderTarget = glctx.get()->getFBOID();
-            desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
-            rt = static_cast<GrRenderTarget*>(context->createPlatformSurface(desc));
+            desc.fRenderTargetHandle = glctx.get()->getFBOID();
+            rt = context->createPlatformRenderTarget(desc);
             if (NULL == rt) {
                 context->unref();
                 context = NULL;
index f2ab703..f437906 100644 (file)
@@ -647,15 +647,13 @@ int main(int argc, char * const argv[]) {
             reinterpret_cast<GrPlatform3DContext>(glContext.get()->gl());
         gGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, ctx);
         if (NULL != gGrContext) {
-            GrPlatformSurfaceDesc desc;
-            desc.reset();
+            GrPlatformRenderTargetDesc desc;
             desc.fConfig = kRGBA_8888_GrPixelConfig;
             desc.fWidth = maxW;
             desc.fHeight = maxH;
             desc.fStencilBits = 8;
-            desc.fPlatformRenderTarget = glContext.get()->getFBOID();
-            desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
-            rt = static_cast<GrRenderTarget*>(gGrContext->createPlatformSurface(desc));
+            desc.fRenderTargetHandle = glContext.get()->getFBOID();
+            rt = gGrContext->createPlatformRenderTarget(desc);
             if (NULL == rt) {
                 gGrContext->unref();
                 gGrContext = NULL;
index d61b8bb..5e132a2 100644 (file)
@@ -238,6 +238,35 @@ public:
     // Platform Surfaces
 
     /**
+     * Wraps an existing texture with a GrTexture object.
+     *
+     * OpenGL: if the object is a texture Gr may change its GL texture params
+     *         when it is drawn.
+     *
+     * @param  desc     description of the object to create.
+     *
+     * @return GrTexture object or NULL on failure.
+     */
+    GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
+
+    /**
+     * Wraps an existing render target with a GrRenderTarget object. It is
+     * similar to createPlatformTexture but can be used to draw into surfaces
+     * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
+     * the client will resolve to a texture).
+     *
+     * @param  desc     description of the object to create.
+     *
+     * @return GrTexture object or NULL on failure.
+     */
+     GrRenderTarget* createPlatformRenderTarget(
+                                    const GrPlatformRenderTargetDesc& desc);
+
+    /**
+     * This interface is depracted and will be removed in a future revision.
+     * Callers should use createPlatformTexture or createPlatformRenderTarget
+     * instead.
+     *
      * Wraps an existing 3D API surface in a GrObject. desc.fFlags determines
      * the type of object returned. If kIsTexture is set the returned object
      * will be a GrTexture*. Otherwise, it will be a GrRenderTarget*. If both 
index 5e9cdb2..cec98a3 100644 (file)
@@ -504,6 +504,99 @@ enum GrConvexHint {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+// opaque type for 3D API object handles
+typedef intptr_t GrPlatform3DObject;
+
+/**
+ * Gr can wrap an existing texture created by the client with a GrTexture
+ * object. The client is responsible for ensuring that the texture lives at
+ * least as long as the GrTexture object wrapping it. We require the client to 
+ * explicitly provide information about the texture, such as width, height, 
+ * and pixel config, rather than querying the 3D APIfor these values. We expect
+ * these to be immutable even if the 3D API doesn't require this (OpenGL).
+ *
+ * Textures that are also render targets are supported as well. Gr will manage
+ * any ancillary 3D API (stencil buffer, FBO id, etc) objects necessary for
+ * Gr to draw into the render target. To access the render target object
+ * call GrTexture::asRenderTarget().
+ *
+ * If in addition to the render target flag, the caller also specifies a sample
+ * count Gr will create an MSAA buffer that resolves into the texture. Gr auto-
+ * resolves when it reads from the texture. The client can explictly resolve
+ * using the GrRenderTarget interface.
+ */
+
+enum GrPlatformTextureFlags {
+    /**
+     * No flags enabled
+     */
+    kNone_GrPlatformTextureFlag              = 0x0,
+    /**
+     * Indicates that the texture is also a render target, and thus should have
+     * a GrRenderTarget object.
+     *
+     * D3D (future): client must have created the texture with flags that allow
+     * it to be used as a render target.
+     */
+    kRenderTarget_GrPlatformTextureFlag      = 0x1,
+};
+GR_MAKE_BITFIELD_OPS(GrPlatformTextureFlags)
+
+struct GrPlatformTextureDesc {
+    GrPlatformTextureDesc() { memset(this, 0, sizeof(*this)); }
+    GrPlatformTextureFlags          fFlags;
+    int                             fWidth;         //<! width in pixels
+    int                             fHeight;        //<! height in pixels
+    GrPixelConfig                   fConfig;        //<! color format
+    /**
+     * If the render target flag is set and sample count is greater than 0
+     * then Gr will create an MSAA buffer that resolves to the texture.
+     */
+    int                             fSampleCnt;
+    /**
+     * Handle to the 3D API object.
+     * OpenGL: Texture ID.
+     */
+    GrPlatform3DObject              fTextureHandle;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Gr can wrap an existing render target created by the client in the 3D API
+ * with a GrRenderTarget object. The client is responsible for ensuring that the
+ * underlying 3D API object lives at least as long as the GrRenderTarget object
+ * wrapping it. We require the client to explicitly provide information about 
+ * the target, such as width, height, and pixel config rather than querying the
+ * 3D API for these values. We expect these properties to be immutable even if
+ * the 3D API doesn't require this (OpenGL).
+ */
+
+struct GrPlatformRenderTargetDesc {
+    GrPlatformRenderTargetDesc() { memset(this, 0, sizeof(*this)); }
+    int                             fWidth;         //<! width in pixels
+    int                             fHeight;        //<! height in pixels
+    GrPixelConfig                   fConfig;        //<! color format
+    /**
+     * The number of samples per pixel. Gr uses this to influence decisions
+     * about applying other forms of antialiasing.
+     */
+    int                             fSampleCnt;
+    /**
+     * Number of bits of stencil per-pixel.
+     */
+    int                             fStencilBits;
+    /**
+     * Handle to the 3D API object.
+     * OpenGL: FBO ID
+     */
+    GrPlatform3DObject              fRenderTargetHandle;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// DEPRECATED. createPlatformSurface is replaced by createPlatformTexture
+// and createPlatformRenderTarget. These enums and structs will be removed.
+
 enum GrPlatformSurfaceType {
     /**
      * Specifies that the object being created is a render target.
@@ -537,12 +630,6 @@ enum GrPlatformRenderTargetFlags {
 
 GR_MAKE_BITFIELD_OPS(GrPlatformRenderTargetFlags)
 
-// opaque type for 3D API object handles
-typedef intptr_t GrPlatform3DObject;
-
-/**
- * Description of platform surface to create. See below for GL example.
- */
 struct GrPlatformSurfaceDesc {
     GrPlatformSurfaceType           fSurfaceType;   // type of surface to create
     /**
index 3b32154..cedc6a5 100644 (file)
@@ -182,34 +182,28 @@ public:
         if (fGrContext) {
             win->attachGL();
 
-            GrPlatformSurfaceDesc desc;
-            desc.reset();
-            desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
+            GrPlatformRenderTargetDesc desc;
             desc.fWidth = SkScalarRound(win->width());
             desc.fHeight = SkScalarRound(win->height());
             desc.fConfig = kRGBA_8888_GrPixelConfig;
-            GR_GL_GetIntegerv(fGL, GR_GL_STENCIL_BITS, &desc.fStencilBits);
             GR_GL_GetIntegerv(fGL, GR_GL_SAMPLES, &desc.fSampleCnt);
+            GR_GL_GetIntegerv(fGL, GR_GL_STENCIL_BITS, &desc.fStencilBits);
             GrGLint buffer;
             GR_GL_GetIntegerv(fGL, GR_GL_FRAMEBUFFER_BINDING, &buffer);
-            desc.fPlatformRenderTarget = buffer;
+            desc.fRenderTargetHandle = buffer;
 
             SkSafeUnref(fGrRenderTarget);
-            fGrRenderTarget = static_cast<GrRenderTarget*>(
-                                            fGrContext->createPlatformSurface(desc));
+            fGrRenderTarget = fGrContext->createPlatformRenderTarget(desc);
         }
         if (NULL != fNullGrContext) {
-            GrPlatformSurfaceDesc desc;
-            desc.reset();
-            desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
+            GrPlatformRenderTargetDesc desc;
             desc.fWidth = SkScalarRound(win->width());
             desc.fHeight = SkScalarRound(win->height());
             desc.fConfig = kRGBA_8888_GrPixelConfig;
             desc.fStencilBits = 8;
             desc.fSampleCnt = 0;
-            desc.fPlatformRenderTarget = 0;
-            fNullGrRenderTarget = static_cast<GrRenderTarget*>(
-                                            fNullGrContext->createPlatformSurface(desc));
+            desc.fRenderTargetHandle = 0;
+            fGrRenderTarget = fNullGrContext->createPlatformRenderTarget(desc);
         }
     }
 
index 231cf23..f4e5e9b 100644 (file)
@@ -525,6 +525,14 @@ int GrContext::getMaxRenderTargetSize() const {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+GrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) {
+    return fGpu->createPlatformTexture(desc);
+}
+
+GrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
+    return fGpu->createPlatformRenderTarget(desc);
+}
+
 GrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc) {
     // validate flags here so that GrGpu subclasses don't have to check
     if (kTexture_GrPlatformSurfaceType == desc.fSurfaceType &&
index 5aeb36d..eb817df 100644 (file)
@@ -67,7 +67,9 @@ public:
         return this->textureFBOID();
     }
     virtual ResolveType getResolveType() const {
-        if (fRTFBOID == fTexFBOID) {
+
+        if (!this->isMultisampled() ||
+            fRTFBOID == fTexFBOID) {
             // catches FBO 0 and non MSAA case
             return kAutoResolves_ResolveType;
         } else if (kUnresolvableFBOID == fTexFBOID) {
index c5a8bfb..b7d1395 100644 (file)
@@ -195,6 +195,25 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
     }
 }
 
+GrTexture* GrGpu::createPlatformTexture(const GrPlatformTextureDesc& desc) {
+    this->handleDirtyContext();
+    GrTexture* tex = this->onCreatePlatformTexture(desc);
+    // TODO: defer this and attach dynamically
+    GrRenderTarget* tgt = tex->asRenderTarget();
+    if (NULL != tgt &&
+        !this->attachStencilBufferToRenderTarget(tgt)) {
+        tex->unref();
+        return NULL;
+    } else {
+        return tex;
+    }
+}
+
+GrRenderTarget* GrGpu::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
+    this->handleDirtyContext();
+    return this->onCreatePlatformRenderTarget(desc);
+}
+
 GrResource* GrGpu::createPlatformSurface(const GrPlatformSurfaceDesc& desc) {
     this->handleDirtyContext();
     return this->onCreatePlatformSurface(desc);
index 5d9cf4f..b0aaa18 100644 (file)
@@ -121,6 +121,19 @@ public:
     GrTexture* createTexture(const GrTextureDesc& desc,
                              const void* srcData, size_t rowBytes);
 
+    /**
+     * Implements GrContext::createPlatformTexture
+     */
+    GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
+
+    /**
+     * Implements GrContext::createPlatformTexture
+     */
+    GrRenderTarget* createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc);
+
+    /**
+     * DEPRECATED. This will be removed.
+     */
     GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
 
     /**
@@ -314,6 +327,8 @@ protected:
     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
                                        const void* srcData,
                                        size_t rowBytes) = 0;
+    virtual GrTexture* onCreatePlatformTexture(const GrPlatformTextureDesc& desc) = 0;
+    virtual GrRenderTarget* onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) = 0;
     virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
                                                  bool dynamic) = 0;
index 10c0fa6..bae4f77 100644 (file)
@@ -634,6 +634,81 @@ void GrGpuGL::onResetContext() {
     fHWDrawState.fRenderTarget = NULL;
 }
 
+GrTexture* GrGpuGL::onCreatePlatformTexture(const GrPlatformTextureDesc& desc) {
+    GrGLenum internalFormat; // we don't need this value
+    GrGLTexture::Desc glTexDesc;
+    if (!this->canBeTexture(desc.fConfig, &internalFormat, 
+                            &glTexDesc.fUploadFormat, &glTexDesc.fUploadType)) {
+        return NULL;
+    }
+    
+    glTexDesc.fContentWidth = glTexDesc.fAllocWidth = desc.fWidth;
+    glTexDesc.fContentHeight = glTexDesc.fAllocHeight = desc.fHeight;
+    glTexDesc.fConfig = desc.fConfig;
+    glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
+    glTexDesc.fOwnsID = false;
+    glTexDesc.fOrientation = GrGLTexture::kBottomUp_Orientation;
+
+    GrGLTexture* texture = NULL;
+    if (desc.fFlags & kRenderTarget_GrPlatformTextureFlag) {
+        GrGLRenderTarget::Desc glRTDesc;
+        glRTDesc.fRTFBOID = 0;
+        glRTDesc.fTexFBOID = 0;
+        glRTDesc.fMSColorRenderbufferID = 0;
+        glRTDesc.fOwnIDs = true;
+        glRTDesc.fConfig = desc.fConfig;
+        glRTDesc.fSampleCnt = desc.fSampleCnt;
+        if (!this->createRenderTargetObjects(glTexDesc.fAllocWidth,
+                                             glTexDesc.fAllocHeight,
+                                             glTexDesc.fTextureID,
+                                             &glRTDesc)) {
+            return NULL;
+        }
+        texture = new GrGLTexture(this, glTexDesc, glRTDesc);
+    } else {
+        texture = new GrGLTexture(this, glTexDesc);
+    }
+    if (NULL == texture) {
+        return NULL;
+    }
+    
+    this->setSpareTextureUnit();
+    return texture;
+}
+
+GrRenderTarget* GrGpuGL::onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
+    GrGLRenderTarget::Desc glDesc;
+    glDesc.fConfig = desc.fConfig;
+    glDesc.fRTFBOID = static_cast<GrGLuint>(desc.fRenderTargetHandle);
+    glDesc.fMSColorRenderbufferID = 0;
+    glDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
+    glDesc.fSampleCnt = desc.fSampleCnt;
+    glDesc.fOwnIDs = false;
+    GrGLIRect viewport;
+    viewport.fLeft   = 0;
+    viewport.fBottom = 0;
+    viewport.fWidth  = desc.fWidth;
+    viewport.fHeight = desc.fHeight;
+    
+    GrRenderTarget* tgt = new GrGLRenderTarget(this, glDesc, viewport);
+    if (desc.fStencilBits) {
+        GrGLStencilBuffer::Format format;
+        format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat;
+        format.fPacked = false;
+        format.fStencilBits = desc.fStencilBits;
+        format.fTotalBits = desc.fStencilBits;
+        GrGLStencilBuffer* sb = new GrGLStencilBuffer(this,
+                                                      0,
+                                                      desc.fWidth,
+                                                      desc.fHeight,
+                                                      desc.fSampleCnt,
+                                                      format);
+        tgt->setStencilBuffer(sb);
+        sb->unref();
+    }
+    return tgt;
+}
+
 GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) {
 
     bool isTexture = kTexture_GrPlatformSurfaceType == desc.fSurfaceType ||
@@ -868,7 +943,10 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
 
     // If we are using multisampling we will create two FBOS. We render
     // to one and then resolve to the texture bound to the other.
-    if (desc->fSampleCnt > 1 && GLCaps::kNone_MSFBO != fGLCaps.fMSFBOType) {
+    if (desc->fSampleCnt > 0) {
+        if (GLCaps::kNone_MSFBO == fGLCaps.fMSFBOType) {
+            goto FAILED;
+        }
         GL_CALL(GenFramebuffers(1, &desc->fRTFBOID));
         GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID));
         if (!desc->fRTFBOID ||
@@ -949,12 +1027,6 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
     ++fStats.fTextureCreateCnt;
 #endif
 
-    static const GrGLTexture::TexParams DEFAULT_PARAMS = {
-        GR_GL_NEAREST,
-        GR_GL_CLAMP_TO_EDGE,
-        GR_GL_CLAMP_TO_EDGE
-    };
-
     GrGLTexture::Desc glTexDesc;
     GrGLRenderTarget::Desc  glRTDesc;
     GrGLenum internalFormat;
@@ -1025,24 +1097,32 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
 
     this->setSpareTextureUnit();
     GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
+
+    // Some drivers like to know these before seeing glTexImage2D. Some drivers
+    // have a bug where an FBO won't be complete if it includes a texture that
+    // is not complete (i.e. has mip levels or non-mip min filter).
+    static const GrGLTexture::TexParams DEFAULT_TEX_PARAMS = {
+        GR_GL_NEAREST,
+        GR_GL_CLAMP_TO_EDGE,
+        GR_GL_CLAMP_TO_EDGE
+    };
     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                           GR_GL_TEXTURE_MAG_FILTER,
-                          DEFAULT_PARAMS.fFilter));
+                          DEFAULT_TEX_PARAMS.fFilter));
     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                           GR_GL_TEXTURE_MIN_FILTER,
-                          DEFAULT_PARAMS.fFilter));
+                          DEFAULT_TEX_PARAMS.fFilter));
     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                           GR_GL_TEXTURE_WRAP_S,
-                          DEFAULT_PARAMS.fWrapS));
+                          DEFAULT_TEX_PARAMS.fWrapS));
     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                           GR_GL_TEXTURE_WRAP_T,
-                          DEFAULT_PARAMS.fWrapT));
+                          DEFAULT_TEX_PARAMS.fWrapT));
 
     this->allocateAndUploadTexData(glTexDesc, internalFormat,srcData, rowBytes);
 
     GrGLTexture* tex;
     if (renderTarget) {
-        GrGLenum msColorRenderbufferFormat = -1;
 #if GR_COLLECT_STATS
         ++fStats.fRenderTargetCreateCnt;
 #endif
@@ -1057,7 +1137,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
     } else {
         tex = new GrGLTexture(this, glTexDesc);
     }
-    tex->setCachedTexParams(DEFAULT_PARAMS, this->getResetTimestamp());
+    tex->setCachedTexParams(DEFAULT_TEX_PARAMS, this->getResetTimestamp());
 #ifdef TRACE_TEXTURE_CREATION
     GrPrintf("--- new texture [%d] size=(%d %d) config=%d\n",
              glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
index f28f578..0addf4a 100644 (file)
@@ -80,6 +80,8 @@ protected:
     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
                                                bool dynamic);
     virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc);
+    virtual GrTexture* onCreatePlatformTexture(const GrPlatformTextureDesc& desc) SK_OVERRIDE;
+    virtual GrRenderTarget* onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) SK_OVERRIDE;
     virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
                                                     int width, int height);
     virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb,