Adding functionality for purgin graphics resource handles
This will allow a fix to WebKit for preventing a crash when the graphics
context is destroyed before the GrContext

BUG=http://code.google.com/p/chromium/issues/detail?id=85309



git-svn-id: http://skia.googlecode.com/svn/trunk@1551 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 58c53ba..8809271 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -66,6 +66,13 @@
     void contextLost();
 
     /**
+     * Similar to contextLost, but makes no attempt to reset state.
+     * Use this method when GrContext destruction is pending, but
+     * the graphics context is destroyed first.
+     */
+    void contextDestroyed();
+
+    /**
      * Frees gpu created by the context. Can be called to reduce GPU memory
      * pressure.
      */
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 574a430..5cb885a 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -325,7 +325,7 @@
      * Called to tell Gpu object that all GrResources have been lost and should
      * be abandoned.
      */
-    void abandonResources();
+    virtual void abandonResources();
 
     /**
      * Called to tell Gpu object to release all GrResources.
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 8baa855..4ebf225 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -74,6 +74,11 @@
 }
 
 void GrContext::contextLost() {
+    contextDestroyed();
+    this->setupDrawBuffer();
+}
+
+void GrContext::contextDestroyed() {
     // abandon first to so destructors
     // don't try to free the resources in the API.
     fGpu->abandonResources();
@@ -93,8 +98,6 @@
     fTextureCache->removeAll();
     fFontCache->freeAll();
     fGpu->markContextDirty();
-
-    this->setupDrawBuffer();
 }
 
 void GrContext::resetContext() {
@@ -1245,8 +1248,10 @@
 
 void GrContext::flushDrawBuffer() {
 #if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING
-    fDrawBuffer->playback(fGpu);
-    fDrawBuffer->reset();
+    if (fDrawBuffer) {
+        fDrawBuffer->playback(fGpu);
+        fDrawBuffer->reset();
+    }
 #endif
 }
 
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index 50be67f..0a933b5 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -130,6 +130,11 @@
     }
 };
 
+void GrGpuGLShaders::abandonResources(){
+    INHERITED::abandonResources();
+    fProgramCache->abandon();
+}
+
 void GrGpuGLShaders::DeleteProgram(GrGLProgram::CachedData* programData) {
     GR_GL(DeleteShader(programData->fVShaderID));
     GR_GL(DeleteShader(programData->fFShaderID));
diff --git a/gpu/src/GrGpuGLShaders.h b/gpu/src/GrGpuGLShaders.h
index 9392d1c..557a4e3 100644
--- a/gpu/src/GrGpuGLShaders.h
+++ b/gpu/src/GrGpuGLShaders.h
@@ -31,6 +31,8 @@
 
     virtual void resetContext();
 
+    virtual void abandonResources();
+
 protected:
     // overrides from GrGpu
     virtual bool flushGraphicsState(GrPrimitiveType type);