Get rid of createRenderTargetFrom3DAPIState and associated glGets necessary to support it.

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



git-svn-id: http://skia.googlecode.com/svn/trunk@2144 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
index 0625174..a2d2d75 100644
--- a/bench/benchmain.cpp
+++ b/bench/benchmain.cpp
@@ -5,19 +5,23 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
+
+#include "BenchTimer.h"
+
+#include "GrContext.h"
+#include "GrRenderTarget.h"
+
+#include "SkBenchmark.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
+#include "SkEGLContext.h"
+#include "SkGpuDevice.h"
 #include "SkGraphics.h"
 #include "SkImageEncoder.h"
 #include "SkNWayCanvas.h"
 #include "SkPicture.h"
 #include "SkString.h"
-#include "GrContext.h"
-#include "SkGpuDevice.h"
-#include "SkEGLContext.h"
-
-#include "SkBenchmark.h"
-#include "BenchTimer.h"
 
 #ifdef ANDROID
 static void log_error(const char msg[]) { SkDebugf("%s", msg); }
@@ -169,7 +173,8 @@
 };
 
 static SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
-                             Backend backend, GrContext* context) {
+                             Backend backend, GrContext* context,
+                             GrRenderTarget* rt) {
     SkDevice* device = NULL;
     SkBitmap bitmap;
     bitmap.setConfig(config, size.fX, size.fY);
@@ -181,7 +186,7 @@
             device = new SkDevice(bitmap);
             break;
         case kGPU_Backend:
-            device = new SkGpuDevice(context, SkGpuDevice::Current3DApiRenderTarget());
+            device = new SkGpuDevice(context, rt);
 //            device->clear(0xFFFFFFFF);
             break;
         case kPDF_Backend:
@@ -408,11 +413,27 @@
     }
     
     GrContext* context = NULL;
+    GrRenderTarget* rt = NULL;
     //Don't do GL when fixed.
 #if !defined(SK_SCALAR_IS_FIXED)
     SkEGLContext eglContext;
     if (eglContext.init(1024, 1024)) {
         context = GrContext::CreateGLShaderContext();
+        if (NULL != context) {
+            GrPlatformSurfaceDesc desc;
+            desc.reset();
+            desc.fConfig = kRGBA_8888_GrPixelConfig;
+            desc.fWidth = 1024;
+            desc.fHeight = 1024;
+            desc.fStencilBits = 8;
+            desc.fPlatformRenderTarget = eglContext.getFBOID();
+            desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
+            rt = static_cast<GrRenderTarget*>(context->createPlatformSurface(desc));
+            if (NULL == rt) {
+                context->unref();
+                context = NULL;
+            }
+        }
     }
 #endif
     
@@ -457,7 +478,8 @@
                 continue;
             }
             
-            SkDevice* device = make_device(outConfig, dim, backend, context);
+            SkDevice* device = make_device(outConfig, dim,
+                                           backend, context, rt);
             SkCanvas canvas(device);
             device->unref();
             
@@ -516,6 +538,9 @@
         }
         log_progress("\n");
     }
-    
+
+    SkSafeUnref(context);
+    SkSafeUnref(rt);
+
     return 0;
 }
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 5252e80..6f7f67b 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -6,8 +6,16 @@
  * found in the LICENSE file.
  */
 #include "gm.h"
+
+#include "GrContext.h"
+#include "GrRenderTarget.h"
+
 #include "SkColorPriv.h"
 #include "SkData.h"
+#include "SkDevice.h"
+#include "SkEGLContext.h"
+#include "SkGpuCanvas.h"
+#include "SkGpuDevice.h"
 #include "SkGraphics.h"
 #include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
@@ -15,12 +23,6 @@
 #include "SkStream.h"
 #include "SkRefCnt.h"
 
-#include "GrContext.h"
-#include "SkGpuCanvas.h"
-#include "SkGpuDevice.h"
-#include "SkEGLContext.h"
-#include "SkDevice.h"
-
 #ifdef SK_SUPPORT_PDF
     #include "SkPDFDevice.h"
     #include "SkPDFDocument.h"
@@ -228,6 +230,7 @@
 // halt.
 static bool generate_image(GM* gm, const ConfigData& gRec,
                            GrContext* context,
+                           GrRenderTarget* rt,
                            SkBitmap* bitmap) {
     SkISize size (gm->getISize());
     setup_bitmap(gRec, size, bitmap);
@@ -239,8 +242,6 @@
         if (NULL == context) {
             return false;
         }
-        // not a real object, so don't unref it
-        GrRenderTarget* rt = SkGpuDevice::Current3DApiRenderTarget();
         SkGpuCanvas gc(context, rt);
         gc.setDevice(new SkGpuDevice(context, rt))->unref();
         gm->draw(&gc);
@@ -406,14 +407,15 @@
                          const char readPath [],
                          const char diffPath [],
                          GrContext* context,
+                         GrRenderTarget* rt,
                          SkBitmap* bitmap) {
     SkDynamicMemoryWStream pdf;
 
     if (gRec.fBackend == kRaster_Backend ||
-            gRec.fBackend == kGPU_Backend) {
+        gRec.fBackend == kGPU_Backend) {
         // Early exit if we can't generate the image, but this is
         // expected in some cases, so don't report a test failure.
-        if (!generate_image(gm, gRec, context, bitmap)) {
+        if (!generate_image(gm, gRec, context, rt, bitmap)) {
             return true;
         }
     } else if (gRec.fBackend == kPDF_Backend) {
@@ -555,11 +557,26 @@
     }
     // setup a GL context for drawing offscreen
     SkEGLContext eglContext;
+    GrRenderTarget* rt = NULL;
     if (eglContext.init(maxW, maxH)) {
         gGrContext = GrContext::CreateGLShaderContext();
+        if (NULL != gGrContext) {
+            GrPlatformSurfaceDesc desc;
+            desc.reset();
+            desc.fConfig = kRGBA_8888_GrPixelConfig;
+            desc.fWidth = maxW;
+            desc.fHeight = maxH;
+            desc.fStencilBits = 8;
+            desc.fPlatformRenderTarget = eglContext.getFBOID();
+            desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
+            rt = static_cast<GrRenderTarget*>(gGrContext->createPlatformSurface(desc));
+            if (NULL == rt) {
+                gGrContext->unref();
+                gGrContext = NULL;
+            }
+        }
     }
 
-
     if (readPath) {
         fprintf(stderr, "reading from %s\n", readPath);
     } else if (writePath) {
@@ -585,7 +602,7 @@
         for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
             bool testSuccess = test_drawing(gm, gRec[i],
                          writePath, readPath, diffPath, gGrContext,
-                         &forwardRenderedBitmap);
+                         rt, &forwardRenderedBitmap);
             overallSuccess &= testSuccess;
 
             if (doReplay && testSuccess) {
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index ee16321..2f98cdf 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -251,20 +251,6 @@
      */
     GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
 
-    /**
-     * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
-     * viewport state from the underlying 3D API and wraps it in a
-     * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
-     * underlying object in its destructor and it is up to caller to guarantee
-     * that it remains valid while the GrRenderTarget is used.
-     *
-     * Will not detect that the render target is also a texture. If you need
-     * to also use the render target as a GrTexture use createPlatformSurface.
-     *
-     * @return the newly created GrRenderTarget
-     */
-    GrRenderTarget* createRenderTargetFrom3DApiState();
-
     ///////////////////////////////////////////////////////////////////////////
     // Matrix state
 
diff --git a/gpu/include/GrRenderTarget.h b/gpu/include/GrRenderTarget.h
index 6fa9f0f..dd7a371 100644
--- a/gpu/include/GrRenderTarget.h
+++ b/gpu/include/GrRenderTarget.h
@@ -62,7 +62,7 @@
      * if client asked us to render to a target that has a pixel
      * config that isn't equivalent with one of our configs.
      */
-    int config() const { return fConfig; }
+    GrPixelConfig config() const { return fConfig; }
 
     /**
      * @return the texture associated with the rendertarget, may be NULL.
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 506cb9f..9c3f298 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -548,10 +548,6 @@
     return fGpu->createPlatformSurface(desc);
 }
 
-GrRenderTarget* GrContext::createRenderTargetFrom3DApiState() {
-    return fGpu->createRenderTargetFrom3DApiState();
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 7744e6a..24950c4 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -196,11 +196,6 @@
     }
 }
 
-GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() {
-    this->handleDirtyContext();
-    return this->onCreateRenderTargetFrom3DApiState();
-}
-
 GrResource* GrGpu::createPlatformSurface(const GrPlatformSurfaceDesc& desc) {
     this->handleDirtyContext();
     return this->onCreatePlatformSurface(desc);
diff --git a/gpu/src/GrGpu.h b/gpu/src/GrGpu.h
index e1e85f7..deaba67 100644
--- a/gpu/src/GrGpu.h
+++ b/gpu/src/GrGpu.h
@@ -123,17 +123,6 @@
     GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
 
     /**
-     * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
-     * viewport state from the underlying 3D API and wraps it in a
-     * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
-     * underlying object in its destructor and it is up to caller to guarantee
-     * that it remains valid while the GrRenderTarget is used.
-     *
-     * @return the newly created GrRenderTarget
-     */
-    GrRenderTarget* createRenderTargetFrom3DApiState();
-
-    /**
      * Creates a vertex buffer.
      *
      * @param size    size in bytes of the vertex buffer
@@ -427,7 +416,6 @@
                                        const void* srcData,
                                        size_t rowBytes) = 0;
     virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
-    virtual GrRenderTarget* onCreateRenderTargetFrom3DApiState() = 0;
     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
                                                  bool dynamic) = 0;
     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 35e918b..ba7615d 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -154,11 +154,6 @@
 
 static bool fbo_test(const GrGLInterface* gl, int w, int h) {
 
-    GrGLint savedFBO;
-    GrGLint savedTexUnit;
-    GR_GL_GetIntegerv(gl, GR_GL_ACTIVE_TEXTURE, &savedTexUnit);
-    GR_GL_GetIntegerv(gl, GR_GL_FRAMEBUFFER_BINDING, &savedFBO);
-
     GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT));
 
     GrGLuint testFBO;
@@ -182,9 +177,6 @@
     GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO));
     GR_GL_CALL(gl, DeleteTextures(1, &testRTTex));
 
-    GR_GL_CALL(gl, ActiveTexture(savedTexUnit));
-    GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, savedFBO));
-
     return status == GR_GL_FRAMEBUFFER_COMPLETE;
 }
 
@@ -710,193 +702,8 @@
     }
 }
 
-namespace {
-
-static const GrGLenum kUnknownGLFormat = ~0;
-
-GrGLenum get_fbo_color_format(const GrGLInterface* gl) {
-    GrGLint cbType;
-    GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                                    GR_GL_COLOR_ATTACHMENT0,
-                                    GR_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
-                                    &cbType);
-    GrGLint cbID;
-    GrGLint cbFormat;
-    switch (cbType) {
-        case GR_GL_RENDERBUFFER:
-            GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                                    GR_GL_COLOR_ATTACHMENT0,
-                                    GR_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
-                                    &cbID);
-            GR_GL_CALL(gl, BindRenderbuffer(GR_GL_RENDERBUFFER, cbID));
-            GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
-                                             GR_GL_RENDERBUFFER_INTERNAL_FORMAT,
-                                             &cbFormat);
-            return cbFormat;
-            break;
-        case GR_GL_TEXTURE:
-            // ES doesn't have glGetTexLevelParameter
-            if (gl->supportsDesktop()) {
-                GrGLint cbLevel;
-                GrGLint cbFace;
-                GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                                    GR_GL_COLOR_ATTACHMENT0,
-                                    GR_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
-                                    &cbID);
-                GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                                    GR_GL_COLOR_ATTACHMENT0,
-                                    GR_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
-                                    &cbLevel);
-                GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                            GR_GL_COLOR_ATTACHMENT0,
-                            GR_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
-                            &cbFace);
-                GrGLenum bind;
-                GrGLenum target;
-                if (cbFace) {
-                    bind = GR_GL_TEXTURE_CUBE_MAP;
-                    target = cbFace;
-                } else {
-                    bind = GR_GL_TEXTURE_2D;
-                    target = GR_GL_TEXTURE_2D;
-                }
-                GR_GL_CALL(gl, BindTexture(bind, cbID));
-                GR_GL_GetTexLevelParameteriv(gl, target, cbLevel, 
-                                    GR_GL_TEXTURE_INTERNAL_FORMAT, &cbFormat);
-                return cbFormat;
-            } else {
-                return kUnknownGLFormat;
-            }
-            break;
-        default:
-            // we can get here with FBO 0, not a render buffer or a texture
-            return kUnknownGLFormat;
-    }
-}
-
-GrPixelConfig internal_color_format_to_config(GrGLenum iFormat) {
-    switch (iFormat) {
-        case GR_GL_RGB565:
-            return kRGB_565_GrPixelConfig;
-        case GR_GL_RGBA4:
-            return kRGBA_4444_GrPixelConfig;
-        case GR_GL_RGBA8:
-        case GR_GL_SRGB8_ALPHA8:
-        case GR_GL_SRGB_ALPHA:
-        case GR_GL_RGBA:
-        case GR_GL_BGRA:
-            return kRGBA_8888_GrPixelConfig;
-        case GR_GL_RGB8:
-        case GR_GL_SRGB8:
-        case GR_GL_SRGB:
-            return kRGBX_8888_GrPixelConfig;
-        default:
-            // there are many GL formats we don't have enums
-            // for. We should still render to them if the client
-            // asks us.
-            return kUnknown_GrPixelConfig;
-    }
-}
-
-GrPixelConfig get_implied_color_config(const GrGLInterface* gl,
-                                       bool arbFBOExtension) {
-    GrGLint rSize, bSize, gSize, aSize;
-    if (arbFBOExtension) {
-        GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER, 
-                GR_GL_COLOR_ATTACHMENT0,
-                GR_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &rSize);
-        GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                GR_GL_COLOR_ATTACHMENT0,
-                GR_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, &gSize);
-        GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER, 
-                GR_GL_COLOR_ATTACHMENT0,
-                GR_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, &bSize);
-        GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                GR_GL_COLOR_ATTACHMENT0, 
-                GR_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &aSize);
-    } else {
-        GR_GL_GetIntegerv(gl, GR_GL_RED_BITS, &rSize);
-        GR_GL_GetIntegerv(gl, GR_GL_GREEN_BITS, &gSize);
-        GR_GL_GetIntegerv(gl, GR_GL_BLUE_BITS, &bSize);
-        GR_GL_GetIntegerv(gl, GR_GL_ALPHA_BITS, &aSize);
-    }
-
-    if(8 == rSize && 8 == gSize && 8 == bSize) {
-       if (0 == aSize) {
-           return kRGBX_8888_GrPixelConfig;
-       } else if (8 == aSize) {
-           return kRGBA_8888_GrPixelConfig;
-       }
-    } else if (4 == rSize && 4 == gSize && 4 == bSize && 4 == aSize) {
-        return kRGBA_4444_GrPixelConfig;
-    } else if (5 == rSize && 6 == gSize && 5 == bSize && 0 == aSize) {
-        return kRGB_565_GrPixelConfig;
-    }
-    return kUnknown_GrPixelConfig;
-}
-
-int get_fbo_stencil_bits(const GrGLInterface* gl, bool arbFBOExtension) {
-    GrGLint stencilBits;
-    if (arbFBOExtension) {
-        GR_GL_GetFramebufferAttachmentParameteriv(gl, GR_GL_FRAMEBUFFER,
-                                    GR_GL_STENCIL_ATTACHMENT,
-                                    GR_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
-                                    &stencilBits);
-    } else {
-        GR_GL_GetIntegerv(gl, GR_GL_STENCIL_BITS, &stencilBits);
-    }
-    return stencilBits;
-}
-}
-
-GrRenderTarget* GrGpuGL::onCreateRenderTargetFrom3DApiState() {
-
-    GrGLRenderTarget::Desc rtDesc;
-
-    GR_GL_GetIntegerv(this->glInterface(), GR_GL_FRAMEBUFFER_BINDING, 
-                      (GrGLint*)&rtDesc.fRTFBOID);
-    rtDesc.fTexFBOID = rtDesc.fRTFBOID;
-    rtDesc.fMSColorRenderbufferID = 0;
-
-    bool arbFBO = ((kDesktop_GrGLBinding == fGLBinding) && (fGLVersion > 3.0 ||
-                   this->hasExtension("GL_ARB_framebuffer_object")));
-
-    GrGLIRect viewport;
-    viewport.setFromGLViewport(this->glInterface());
-    int stencilBits = get_fbo_stencil_bits(this->glInterface(), arbFBO);
-    GR_GL_GetIntegerv(this->glInterface(), GR_GL_SAMPLES, &rtDesc.fSampleCnt);
-
-    SkAutoTUnref<GrGLStencilBuffer> sb;
-    if (stencilBits) {
-        GrGLStencilBuffer::Format format;
-        // we could query this but we don't really need it
-        format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat;
-        format.fPacked = false;
-        format.fStencilBits = stencilBits;
-        format.fTotalBits = stencilBits;
-        sb.reset(new GrGLStencilBuffer(this, 0, viewport.fWidth,
-                                       viewport.fHeight, rtDesc.fSampleCnt,
-                                       format));
-    }
-
-    GrGLenum fmat = get_fbo_color_format(this->glInterface());
-    if (kUnknownGLFormat == fmat) {
-        rtDesc.fConfig = get_implied_color_config(this->glInterface(), arbFBO);
-    } else {
-        rtDesc.fConfig = internal_color_format_to_config(fmat);
-    }
-
-    // may have to bind a texture to gets its format
-    this->setSpareTextureUnit();
-
-    rtDesc.fOwnIDs = false;
-
-    GrGLRenderTarget* target = new GrGLRenderTarget(this, rtDesc, viewport);
-    target->setStencilBuffer(sb.get());
-    return target;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
+
 static const GrGLuint kUnknownBitCount = ~0;
 
 void GrGpuGL::setupStencilFormats() {
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index fc104c1..b45928f 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -82,7 +82,6 @@
     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
                                                bool dynamic);
     virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc);
-    virtual GrRenderTarget* onCreateRenderTargetFrom3DApiState();
     virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
                                                     int width, int height);
     virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index 748cf1a..11dc993 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -256,8 +256,6 @@
 GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
     : GrGpuGL(gl, get_binding_in_use(gl)) {
 
-    resetContext();
-
     f4X4DownsampleFilterSupport = true;
     if (kDesktop_GrGLBinding == this->glBinding()) {
         fDualSourceBlendingSupport =
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index a46314e..f5613a7 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -50,13 +50,6 @@
      */
     SkGpuDevice(GrContext*, GrTexture*);
 
-    /**
-     * Magic value that can be passed to constructor. Causes
-     * the device to infer rendertarget from underlying 3D API (e.g. GL or D3D).
-     * This isn't a valid pointer, don't attempt to dereference.
-     */
-    static GrRenderTarget* Current3DApiRenderTarget();
-
     virtual ~SkGpuDevice();
 
     GrContext* context() const { return fContext; }
diff --git a/include/utils/SkEGLContext.h b/include/utils/SkEGLContext.h
index 9d3b7d1..7188ffb 100644
--- a/include/utils/SkEGLContext.h
+++ b/include/utils/SkEGLContext.h
@@ -23,7 +23,7 @@
 #endif
 
 /**
- *  Create an offscreen opengl context
+ *  Create an offscreen opengl context with an RGBA8 / 8bit stencil FBO.
  */
 class SkEGLContext {
 public:
@@ -32,7 +32,10 @@
 
     bool init(const int width, const int height);
 
+    int getFBOID() const { return fFBO; }
+
 private:
+    GLuint fFBO;
 #if defined(SK_MESA)
     OSMesaContext context;
     GLfloat *image;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 9fe54e5..105c456 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -104,10 +104,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrRenderTarget* SkGpuDevice::Current3DApiRenderTarget() {
-    return (GrRenderTarget*) -1;
-}
-
 static SkBitmap::Config grConfig2skConfig(GrPixelConfig config, bool* isOpaque) {
     switch (config) {
         case kAlpha_8_GrPixelConfig:
@@ -130,13 +126,7 @@
 }
 
 static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
-    SkAutoTUnref<GrRenderTarget> rtunref;
-    if (SkGpuDevice::Current3DApiRenderTarget() == renderTarget) {
-        renderTarget = context->createRenderTargetFrom3DApiState();
-        rtunref.reset(renderTarget);
-    }
-    GrTexture* texture = renderTarget->asTexture();
-    GrPixelConfig config = texture ? texture->config() : kRGBA_8888_GrPixelConfig;
+    GrPixelConfig config = renderTarget->config();
 
     bool isOpaque;
     SkBitmap bitmap;
@@ -168,16 +158,12 @@
     fRenderTarget = NULL;
     fNeedClear = false;
     
-    if (Current3DApiRenderTarget() == renderTarget) {
-        fRenderTarget = fContext->createRenderTargetFrom3DApiState();
-    } else {
-        GrAssert(NULL != renderTarget);
-        fRenderTarget = renderTarget;
-        fRenderTarget->ref();
-        // if this RT is also a texture, hold a ref on it
-        fTexture = fRenderTarget->asTexture();
-        SkSafeRef(fTexture);
-    }
+    GrAssert(NULL != renderTarget);
+    fRenderTarget = renderTarget;
+    fRenderTarget->ref();
+    // if this RT is also a texture, hold a ref on it
+    fTexture = fRenderTarget->asTexture();
+    SkSafeRef(fTexture);
 
     SkGrRenderTargetPixelRef* pr = new SkGrRenderTargetPixelRef(fRenderTarget);
     this->setPixelRef(pr, 0)->unref();
diff --git a/src/utils/SkEGLContext_none.cpp b/src/utils/SkEGLContext_none.cpp
index 25f8513..52ea5ef 100644
--- a/src/utils/SkEGLContext_none.cpp
+++ b/src/utils/SkEGLContext_none.cpp
@@ -7,7 +7,8 @@
  */
 #include "SkEGLContext.h"
 
-SkEGLContext::SkEGLContext() {
+SkEGLContext::SkEGLContext()
+    : fFBO(0) {
 }
 
 SkEGLContext::~SkEGLContext() {
diff --git a/src/utils/mac/SkEGLContext_mac.cpp b/src/utils/mac/SkEGLContext_mac.cpp
index d237795..579be4b 100644
--- a/src/utils/mac/SkEGLContext_mac.cpp
+++ b/src/utils/mac/SkEGLContext_mac.cpp
@@ -9,7 +9,9 @@
 //#include "SkTypes.h"
 #include <AGL/agl.h>
 
-SkEGLContext::SkEGLContext() : context(NULL) {
+SkEGLContext::SkEGLContext() 
+    : fFBO(0)
+    , context(NULL) {
 }
 
 SkEGLContext::~SkEGLContext() {
@@ -53,11 +55,10 @@
 
     // Now create our FBO render target
 
-    GLuint fboID;
     GLuint cbID;
     GLuint dsID;
-    glGenFramebuffersEXT(1, &fboID);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
+    glGenFramebuffersEXT(1, &fFBO);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFBO);
     glGenRenderbuffers(1, &cbID);
     glBindRenderbuffer(GL_RENDERBUFFER, cbID);
     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, width, height);
diff --git a/src/utils/mesa/SkEGLContext_Mesa.cpp b/src/utils/mesa/SkEGLContext_Mesa.cpp
index fdb2ac0..1174ded 100644
--- a/src/utils/mesa/SkEGLContext_Mesa.cpp
+++ b/src/utils/mesa/SkEGLContext_Mesa.cpp
@@ -15,7 +15,10 @@
 #define SK_GL_GET_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F);
 #define SK_GL_GET_EXT_PROC(T, F) F ## _func = (T)OSMesaGetProcAddress(#F "EXT");
 
-SkEGLContext::SkEGLContext() : context(NULL), image(NULL) {
+SkEGLContext::SkEGLContext()
+    : fFBO(0)
+    , context(NULL)
+    , image(NULL) {
 }
 
 SkEGLContext::~SkEGLContext() {
@@ -110,11 +113,10 @@
       return false;
     }
     
-    GLuint fboID;
     GLuint cbID;
     GLuint dsID;
-    glGenFramebuffers_func(1, &fboID);
-    glBindFramebuffer_func(GL_FRAMEBUFFER, fboID);
+    glGenFramebuffers_func(1, &fFBO);
+    glBindFramebuffer_func(GL_FRAMEBUFFER, fFBO);
     
     glGenRenderbuffers_func(1, &cbID);
     glBindRenderbuffer_func(GL_RENDERBUFFER, cbID);
diff --git a/src/utils/unix/SkEGLContext_Unix.cpp b/src/utils/unix/SkEGLContext_Unix.cpp
index 6eb7e35..40a1b5d 100644
--- a/src/utils/unix/SkEGLContext_Unix.cpp
+++ b/src/utils/unix/SkEGLContext_Unix.cpp
@@ -23,7 +23,12 @@
     return 0;
 }
 
-SkEGLContext::SkEGLContext() : context(NULL), display(NULL), pixmap(0), glxPixmap(0) {
+SkEGLContext::SkEGLContext() 
+    : fFBO(0)
+    , context(NULL)
+    , display(NULL)
+    , pixmap(0)
+    , glxPixmap(0) {
 }
 
 SkEGLContext::~SkEGLContext() {
@@ -249,11 +254,10 @@
     SK_GL_GET_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbufferEXT)
     SK_GL_GET_PROC(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatusEXT)
 
-    GLuint fboID;
     GLuint cbID;
     GLuint dsID;
-    glGenFramebuffersEXT(1, &fboID);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
+    glGenFramebuffersEXT(1, &fFBO);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFBO);
     glGenRenderbuffersEXT(1, &cbID);
     glBindRenderbufferEXT(GL_RENDERBUFFER, cbID);
     glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, width, height);
diff --git a/src/utils/win/SkEGLContext_Win.cpp b/src/utils/win/SkEGLContext_Win.cpp
index c2483e7..b82e7d7 100644
--- a/src/utils/win/SkEGLContext_Win.cpp
+++ b/src/utils/win/SkEGLContext_Win.cpp
@@ -34,8 +34,9 @@
 typedef void (SK_EGL_FUNCTION_TYPE *SkEGLFramebufferRenderbufferProc) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
 typedef GLenum (SK_EGL_FUNCTION_TYPE *SkEGLCheckFramebufferStatusProc) (GLenum target);
 
-SkEGLContext::SkEGLContext() :
-        fWindow(NULL)
+SkEGLContext::SkEGLContext()
+        : fFBO(0)
+        , fWindow(NULL)
         , fDeviceContext(NULL)
         , fGlRenderContext(0) {
 }
@@ -174,11 +175,10 @@
     SK_EGL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT)
     SK_EGL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT)
 
-    GLuint fboID;
     GLuint cbID;
     GLuint dsID;
-    SkEGLGenFramebuffers(1, &fboID);
-    SkEGLBindFramebuffer(SK_EGL_FRAMEBUFFER, fboID);
+    SkEGLGenFramebuffers(1, &fFBO);
+    SkEGLBindFramebuffer(SK_EGL_FRAMEBUFFER, fFBO);
     SkEGLGenRenderbuffers(1, &cbID);
     SkEGLBindRenderbuffer(SK_EGL_RENDERBUFFER, cbID);
     SkEGLRenderbufferStorage(SK_EGL_RENDERBUFFER, GL_RGBA, width, height);