Give GrDrawTarget a back ptr to its owning GrContext.
Review URL: https://codereview.appspot.com/7395055

git-svn-id: http://skia.googlecode.com/svn/trunk@7850 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 1bbb885..3bdb332 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -991,3 +991,8 @@
 void GrClipMaskManager::releaseResources() {
     fAACache.releaseResources();
 }
+
+void GrClipMaskManager::setGpu(GrGpu* gpu) {
+    fGpu = gpu;
+    fAACache.setContext(gpu->getContext());
+}
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index 534689a..6d9d6f6 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -68,18 +68,11 @@
         }
     }
 
-    void setContext(GrContext* context) {
-        fAACache.setContext(context);
-    }
-
     GrContext* getContext() {
         return fAACache.getContext();
     }
 
-    void setGpu(GrGpu* gpu) {
-        fGpu = gpu;
-    }
-
+    void setGpu(GrGpu* gpu);
 private:
     /**
      * Informs the helper function adjustStencilParams() about how the stencil
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 8ca74c3..0f6fa16 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -63,14 +63,14 @@
 
 #define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this)
 
-GrContext* GrContext::Create(GrBackend backend, GrBackendContext context) {
-    GrContext* ctx = NULL;
-    GrGpu* fGpu = GrGpu::Create(backend, context);
-    if (NULL != fGpu) {
-        ctx = SkNEW_ARGS(GrContext, (fGpu));
-        fGpu->unref();
+GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
+    GrContext* context = SkNEW(GrContext);
+    if (context->init(backend, backendContext)) {
+        return context;
+    } else {
+        context->unref();
+        return NULL;
     }
-    return ctx;
 }
 
 namespace {
@@ -80,10 +80,50 @@
 void DeleteThreadInstanceCount(void* v) {
     delete reinterpret_cast<int*>(v);
 }
-#define THREAD_INSTANCE_COUNT                                               \
-    (*reinterpret_cast<int*>(SkTLS::Get(CreateThreadInstanceCount,          \
-                                        DeleteThreadInstanceCount)))
+#define THREAD_INSTANCE_COUNT \
+    (*reinterpret_cast<int*>(SkTLS::Get(CreateThreadInstanceCount, DeleteThreadInstanceCount)))
+}
 
+GrContext::GrContext() {
+    ++THREAD_INSTANCE_COUNT;
+    fDrawState = NULL;
+    fGpu = NULL;
+    fPathRendererChain = NULL;
+    fSoftwarePathRenderer = NULL;
+    fTextureCache = NULL;
+    fFontCache = NULL;
+    fDrawBuffer = NULL;
+    fDrawBufferVBAllocPool = NULL;
+    fDrawBufferIBAllocPool = NULL;
+    fAARectRenderer = NULL;
+}
+
+bool GrContext::init(GrBackend backend, GrBackendContext backendContext) {
+    GrAssert(NULL == fGpu);
+
+    fGpu = GrGpu::Create(backend, backendContext, this);
+    if (NULL == fGpu) {
+        return false;
+    }
+
+    fDrawState = SkNEW(GrDrawState);
+    fGpu->setDrawState(fDrawState);
+
+
+    fTextureCache = SkNEW_ARGS(GrResourceCache,
+                               (MAX_TEXTURE_CACHE_COUNT,
+                                MAX_TEXTURE_CACHE_BYTES));
+    fFontCache = SkNEW_ARGS(GrFontCache, (fGpu));
+
+    fLastDrawWasBuffered = kNo_BufferedDraw;
+
+    fAARectRenderer = SkNEW(GrAARectRenderer);
+
+    fDidTestPMConversions = false;
+
+    this->setupDrawBuffer();
+
+    return true;
 }
 
 int GrContext::GetThreadInstanceCount() {
@@ -119,7 +159,7 @@
 }
 
 void GrContext::contextLost() {
-    contextDestroyed();
+    this->contextDestroyed();
     this->setupDrawBuffer();
 }
 
@@ -1196,18 +1236,8 @@
 }
 
 void GrContext::flushDrawBuffer() {
-    if (fDrawBuffer) {
-        // With addition of the AA clip path, flushing the draw buffer can
-        // result in the generation of an AA clip mask. During this
-        // process the SW path renderer may be invoked which recusively
-        // calls this method (via internalWriteTexturePixels) creating
-        // infinite recursion
-        GrInOrderDrawBuffer* temp = fDrawBuffer;
-        fDrawBuffer = NULL;
-
-        temp->flushTo(fGpu);
-
-        fDrawBuffer = temp;
+    if (NULL != fDrawBuffer && !fDrawBuffer->isFlushing()) {
+        fDrawBuffer->flush();
     }
 }
 
@@ -1710,37 +1740,6 @@
     return bits;
 }
 
-GrContext::GrContext(GrGpu* gpu) {
-    ++THREAD_INSTANCE_COUNT;
-
-    fGpu = gpu;
-    fGpu->ref();
-    fGpu->setContext(this);
-
-    fDrawState = SkNEW(GrDrawState);
-    fGpu->setDrawState(fDrawState);
-
-    fPathRendererChain = NULL;
-    fSoftwarePathRenderer = NULL;
-
-    fTextureCache = SkNEW_ARGS(GrResourceCache,
-                               (MAX_TEXTURE_CACHE_COUNT,
-                                MAX_TEXTURE_CACHE_BYTES));
-    fFontCache = SkNEW_ARGS(GrFontCache, (fGpu));
-
-    fLastDrawWasBuffered = kNo_BufferedDraw;
-
-    fDrawBuffer = NULL;
-    fDrawBufferVBAllocPool = NULL;
-    fDrawBufferIBAllocPool = NULL;
-
-    fAARectRenderer = SkNEW(GrAARectRenderer);
-
-    fDidTestPMConversions = false;
-
-    this->setupDrawBuffer();
-}
-
 void GrContext::setupDrawBuffer() {
 
     GrAssert(NULL == fDrawBuffer);
@@ -1757,13 +1756,10 @@
                                    DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS));
 
     fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu,
-                                          fDrawBufferVBAllocPool,
-                                          fDrawBufferIBAllocPool));
+                                                   fDrawBufferVBAllocPool,
+                                                   fDrawBufferIBAllocPool));
 
-    if (fDrawBuffer) {
-        fDrawBuffer->setAutoFlushTarget(fGpu);
-        fDrawBuffer->setDrawState(fDrawState);
-    }
+    fDrawBuffer->setDrawState(fDrawState);
 }
 
 GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 7fc2c13..2c2d949 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -82,7 +82,11 @@
 #define DEBUG_INVAL_BUFFER 0xdeadcafe
 #define DEBUG_INVAL_START_IDX -1
 
-GrDrawTarget::GrDrawTarget() : fClip(NULL) {
+GrDrawTarget::GrDrawTarget(GrContext* context)
+    : fClip(NULL)
+    , fContext(context) {
+    GrAssert(NULL != context);
+
     fDrawState = &fDefaultDrawState;
     // We assume that fDrawState always owns a ref to the object it points at.
     fDefaultDrawState.ref();
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index a371a9b..965b1b6 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -88,7 +88,9 @@
 
     ///////////////////////////////////////////////////////////////////////////
 
-    GrDrawTarget();
+    // The context may not be fully constructed and should not be used during GrDrawTarget
+    // construction.
+    GrDrawTarget(GrContext* context);
     virtual ~GrDrawTarget();
 
     /**
@@ -648,6 +650,9 @@
         }
     }
 
+    GrContext* getContext() { return fContext; }
+    const GrContext* getContext() const { return fContext; }
+
     // allows derived class to set the caps
     CapsInternals* capsInternals() { return &fCaps.fInternals; }
 
@@ -774,6 +779,8 @@
     const GrClipData*                                               fClip;
     GrDrawState*                                                    fDrawState;
     GrDrawState                                                     fDefaultDrawState;
+    // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget.
+    GrContext*                                                      fContext;
 
     typedef GrRefCnt INHERITED;
 };
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index c9aa046..b5cdc5c 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -26,8 +26,8 @@
 #define DEBUG_INVAL_BUFFER    0xdeadcafe
 #define DEBUG_INVAL_START_IDX -1
 
-GrGpu::GrGpu()
-    : fContext(NULL)
+GrGpu::GrGpu(GrContext* context)
+    : GrDrawTarget(context)
     , fResetTimestamp(kExpiredTimestamp+1)
     , fVertexPool(NULL)
     , fIndexPool(NULL)
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index d0ca377..41ebb73 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -47,23 +47,18 @@
 
     /**
      * Create an instance of GrGpu that matches the specified backend. If the requested backend is
-     * not supported (at compile-time or run-time) this returns NULL.
+     * not supported (at compile-time or run-time) this returns NULL. The context will not be
+     * fully constructed and should not be used by GrGpu until after this function returns.
      */
-    static GrGpu* Create(GrBackend, GrBackendContext);
+    static GrGpu* Create(GrBackend, GrBackendContext, GrContext* context);
 
     ////////////////////////////////////////////////////////////////////////////
 
-    GrGpu();
+    GrGpu(GrContext* context);
     virtual ~GrGpu();
 
-    // The GrContext sets itself as the owner of this Gpu object
-    void setContext(GrContext* context) {
-        GrAssert(NULL == fContext);
-        fContext = context;
-        fClipMaskManager.setContext(context);
-    }
-    GrContext* getContext() { return fContext; }
-    const GrContext* getContext() const { return fContext; }
+    GrContext* getContext() { return this->INHERITED::getContext(); }
+    const GrContext* getContext() const { return this->INHERITED::getContext(); }
 
     /**
      * The GrGpu object normally assumes that no outsider is setting state
@@ -527,7 +522,6 @@
     };
     typedef SkTInternalLList<GrResource> ResourceList;
     SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true>  fGeomPoolStateStack;
-    GrContext*                                                          fContext; // not reffed
     ResetTimestamp                                                      fResetTimestamp;
     GrVertexBufferAllocPool*                                            fVertexPool;
     GrIndexBufferAllocPool*                                             fIndexPool;
diff --git a/src/gpu/GrGpuFactory.cpp b/src/gpu/GrGpuFactory.cpp
index 63a73b7..a511446 100644
--- a/src/gpu/GrGpuFactory.cpp
+++ b/src/gpu/GrGpuFactory.cpp
@@ -14,13 +14,13 @@
 #include "GrGpu.h"
 #include "gl/GrGpuGL.h"
 
-GrGpu* GrGpu::Create(GrBackend backend, GrBackendContext context) {
+GrGpu* GrGpu::Create(GrBackend backend, GrBackendContext backendContext, GrContext* context) {
 
     const GrGLInterface* glInterface = NULL;
     SkAutoTUnref<const GrGLInterface> glInterfaceUnref;
 
     if (kOpenGL_GrBackend == backend) {
-        glInterface = reinterpret_cast<const GrGLInterface*>(context);
+        glInterface = reinterpret_cast<const GrGLInterface*>(backendContext);
         if (NULL == glInterface) {
             glInterface = GrGLDefaultInterface();
             // By calling GrGLDefaultInterface we've taken a ref on the
@@ -36,7 +36,7 @@
         }
         GrGLContextInfo ctxInfo(glInterface);
         if (ctxInfo.isInitialized()) {
-            return SkNEW_ARGS(GrGpuGL, (ctxInfo));
+            return SkNEW_ARGS(GrGpuGL, (ctxInfo, context));
         }
     }
     return NULL;
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 0ebf810..00aaadb 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -13,21 +13,23 @@
 #include "GrIndexBuffer.h"
 #include "GrPath.h"
 #include "GrRenderTarget.h"
+#include "GrTemplates.h"
 #include "GrTexture.h"
 #include "GrVertexBuffer.h"
 
-GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
+GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
                                          GrVertexBufferAllocPool* vertexPool,
                                          GrIndexBufferAllocPool* indexPool)
-    : fAutoFlushTarget(NULL)
+    : GrDrawTarget(gpu->getContext())
+    , fDstGpu(gpu)
     , fClipSet(true)
     , fClipProxyState(kUnknown_ClipProxyState)
     , fVertexPool(*vertexPool)
     , fIndexPool(*indexPool)
     , fFlushing(false) {
 
-    fGpu.reset(SkRef(gpu));
-    fCaps = gpu->getCaps();
+    fDstGpu->ref();
+    fCaps = fDstGpu->getCaps();
 
     GrAssert(NULL != vertexPool);
     GrAssert(NULL != indexPool);
@@ -48,7 +50,7 @@
     this->reset();
     // This must be called by before the GrDrawTarget destructor
     this->releaseGeometry();
-    GrSafeUnref(fAutoFlushTarget);
+    fDstGpu->unref();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -161,7 +163,7 @@
         }
     }
 
-    this->setIndexSourceToBuffer(fGpu->getQuadIndexBuffer());
+    this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
     this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
 }
 
@@ -411,28 +413,29 @@
     fClipSet = true;
 }
 
-bool GrInOrderDrawBuffer::flushTo(GrDrawTarget* target) {
+bool GrInOrderDrawBuffer::flush() {
     GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
     GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
 
-    GrAssert(NULL != target);
-    GrAssert(target != this); // not considered and why?
-
     int numCmds = fCmds.count();
     if (0 == numCmds) {
         return false;
     }
+    GrAssert(!fFlushing);
+
+    GrAutoTRestore<bool> flushRestore(&fFlushing);
+    fFlushing = true;
 
     fVertexPool.unlock();
     fIndexPool.unlock();
 
-    GrDrawTarget::AutoClipRestore acr(target);
-    AutoGeometryAndStatePush agasp(target, kPreserve_ASRInit);
+    GrDrawTarget::AutoClipRestore acr(fDstGpu);
+    AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit);
 
     GrDrawState playbackState;
-    GrDrawState* prevDrawState = target->drawState();
+    GrDrawState* prevDrawState = fDstGpu->drawState();
     prevDrawState->ref();
-    target->setDrawState(&playbackState);
+    fDstGpu->setDrawState(&playbackState);
 
     GrClipData clipData;
 
@@ -442,23 +445,22 @@
     int currDraw        = 0;
     int currStencilPath = 0;
 
-
     for (int c = 0; c < numCmds; ++c) {
         switch (fCmds[c]) {
             case kDraw_Cmd: {
                 const DrawRecord& draw = fDraws[currDraw];
-                target->setVertexSourceToBuffer(draw.fVertexBuffer);
+                fDstGpu->setVertexSourceToBuffer(draw.fVertexBuffer);
                 if (draw.isIndexed()) {
-                    target->setIndexSourceToBuffer(draw.fIndexBuffer);
+                    fDstGpu->setIndexSourceToBuffer(draw.fIndexBuffer);
                 }
-                target->executeDraw(draw);
+                fDstGpu->executeDraw(draw);
 
                 ++currDraw;
                 break;
             }
             case kStencilPath_Cmd: {
                 const StencilPath& sp = fStencilPaths[currStencilPath];
-                target->stencilPath(sp.fPath.get(), sp.fStroke, sp.fFill);
+                fDstGpu->stencilPath(sp.fPath.get(), sp.fStroke, sp.fFill);
                 ++currStencilPath;
                 break;
             }
@@ -469,13 +471,13 @@
             case kSetClip_Cmd:
                 clipData.fClipStack = &fClips[currClip];
                 clipData.fOrigin = fClipOrigins[currClip];
-                target->setClip(&clipData);
+                fDstGpu->setClip(&clipData);
                 ++currClip;
                 break;
             case kClear_Cmd:
-                target->clear(&fClears[currClear].fRect,
-                              fClears[currClear].fColor,
-                              fClears[currClear].fRenderTarget);
+                fDstGpu->clear(&fClears[currClear].fRect,
+                               fClears[currClear].fColor,
+                               fClears[currClear].fRenderTarget);
                 ++currClear;
                 break;
         }
@@ -487,52 +489,45 @@
     GrAssert(fClears.count() == currClear);
     GrAssert(fDraws.count()  == currDraw);
 
-    target->setDrawState(prevDrawState);
+    fDstGpu->setDrawState(prevDrawState);
     prevDrawState->unref();
     this->reset();
     return true;
 }
 
-void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
-    GrSafeAssign(fAutoFlushTarget, target);
-}
-
 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
                                 int vertexCount,
                                 int indexCount) {
-    if (NULL != fAutoFlushTarget) {
-        // We use geometryHints() to know whether to flush the draw buffer. We
-        // can't flush if we are inside an unbalanced pushGeometrySource.
-        // Moreover, flushing blows away vertex and index data that was
-        // previously reserved. So if the vertex or index data is pulled from
-        // reserved space and won't be released by this request then we can't
-        // flush.
-        bool insideGeoPush = fGeoPoolStateStack.count() > 1;
+    // We use geometryHints() to know whether to flush the draw buffer. We
+    // can't flush if we are inside an unbalanced pushGeometrySource.
+    // Moreover, flushing blows away vertex and index data that was
+    // previously reserved. So if the vertex or index data is pulled from
+    // reserved space and won't be released by this request then we can't
+    // flush.
+    bool insideGeoPush = fGeoPoolStateStack.count() > 1;
 
-        bool unreleasedVertexSpace =
-            !vertexCount &&
-            kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
+    bool unreleasedVertexSpace =
+        !vertexCount &&
+        kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
 
-        bool unreleasedIndexSpace =
-            !indexCount &&
-            kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
+    bool unreleasedIndexSpace =
+        !indexCount &&
+        kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
 
-        // we don't want to finalize any reserved geom on the target since
-        // we don't know that the client has finished writing to it.
-        bool targetHasReservedGeom =
-            fAutoFlushTarget->hasReservedVerticesOrIndices();
+    // we don't want to finalize any reserved geom on the target since
+    // we don't know that the client has finished writing to it.
+    bool targetHasReservedGeom = fDstGpu->hasReservedVerticesOrIndices();
 
-        int vcount = vertexCount;
-        int icount = indexCount;
+    int vcount = vertexCount;
+    int icount = indexCount;
 
-        if (!insideGeoPush &&
-            !unreleasedVertexSpace &&
-            !unreleasedIndexSpace &&
-            !targetHasReservedGeom &&
-            this->geometryHints(&vcount, &icount)) {
+    if (!insideGeoPush &&
+        !unreleasedVertexSpace &&
+        !unreleasedIndexSpace &&
+        !targetHasReservedGeom &&
+        this->geometryHints(&vcount, &icount)) {
 
-            this->flushTo(fAutoFlushTarget);
-        }
+        this->flush();
     }
 }
 
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index b1aa9e9..f04bb84 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -40,15 +40,13 @@
     /**
      * Creates a GrInOrderDrawBuffer
      *
-     * @param gpu        the gpu object where this will be played back
-     *                   (possible indirectly). GrResources used with the draw
-     *                   buffer are created by this gpu object.
+     * @param gpu        the gpu object that this draw buffer flushes to.
      * @param vertexPool pool where vertices for queued draws will be saved when
      *                   the vertex source is either reserved or array.
      * @param indexPool  pool where indices for queued draws will be saved when
      *                   the index source is either reserved or array.
      */
-    GrInOrderDrawBuffer(const GrGpu* gpu,
+    GrInOrderDrawBuffer(GrGpu* gpu,
                         GrVertexBufferAllocPool* vertexPool,
                         GrIndexBufferAllocPool* indexPool);
 
@@ -61,25 +59,16 @@
     void reset();
 
     /**
-     * This plays the queued up draws to another target. It also resets this object (i.e. flushing
+     * This plays the queued up draws to its GrGpu target. It also resets this object (i.e. flushing
      * is destructive). This buffer must not have an active reserved vertex or index source. Any
      * reserved geometry on the target will be finalized because it's geometry source will be pushed
      * before flushing and popped afterwards.
      *
      * @return false if the playback trivially drew nothing because nothing was recorded.
-     *
-     * @param target    the target to receive the playback
      */
-    bool flushTo(GrDrawTarget* target);
+    bool flush();
 
-    /**
-     * This function allows the draw buffer to automatically flush itself to another target. This
-     * means the buffer may internally call this->flushTo(target) when it is safe to do so.
-     *
-     * When the auto flush target is set to NULL (as it initially is) the draw buffer will never
-     * automatically flush itself.
-     */
-    void setAutoFlushTarget(GrDrawTarget* target);
+    bool isFlushing() const { return fFlushing; }
 
     // overrides from GrDrawTarget
     virtual bool geometryHints(int* vertexCount,
@@ -177,8 +166,6 @@
         kGeoPoolStatePreAllocCnt = 4,
     };
 
-    SkAutoTUnref<const GrGpu> fGpu;
-
     SkSTArray<kCmdPreallocCnt, uint8_t, true>                          fCmds;
     GrSTAllocator<kDrawPreallocCnt, DrawRecord>                        fDraws;
     GrSTAllocator<kStatePreallocCnt, StencilPath>                      fStencilPaths;
@@ -188,7 +175,7 @@
     GrSTAllocator<kClipPreallocCnt, SkClipStack>        fClips;
     GrSTAllocator<kClipPreallocCnt, SkIPoint>           fClipOrigins;
 
-    GrDrawTarget*                   fAutoFlushTarget;
+    GrDrawTarget*                   fDstGpu;
 
     bool                            fClipSet;
 
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index b75ab32..a8c9024 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -147,7 +147,9 @@
     return status == GR_GL_FRAMEBUFFER_COMPLETE;
 }
 
-GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo) : fGLContextInfo(ctxInfo) {
+GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo, GrContext* context)
+    : GrGpu(context)
+    , fGLContextInfo(ctxInfo) {
 
     GrAssert(ctxInfo.isInitialized());
 
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 8d1e7dd..b47865c 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -24,7 +24,7 @@
 
 class GrGpuGL : public GrGpu {
 public:
-    GrGpuGL(const GrGLContextInfo& ctxInfo);
+    GrGpuGL(const GrGLContextInfo& ctxInfo, GrContext* context);
     virtual ~GrGpuGL();
 
     const GrGLInterface* glInterface() const {