Driver bug workaround: restore_scissor_on_fbo_change

Bug: chromium: 829614
Change-Id: I333aed9a378ab9b7aafaa96bb495378d1db4a61d
Reviewed-on: https://skia-review.googlesource.com/127118
Commit-Queue: Adrienne Walker <enne@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 908d367..d957eb3 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1353,6 +1353,7 @@
         fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
     }
 
+    this->didBindFramebuffer();
     return true;
 
 FAILED:
@@ -2475,6 +2476,7 @@
     if (fHWBoundRenderTargetUniqueID != rtID) {
         fStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
+        this->didBindFramebuffer();
 #ifdef SK_DEBUG
         // don't do this check in Chromium -- this is causing
         // lots of repeated command buffer flushes when the compositor is
@@ -3379,6 +3381,7 @@
         GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
         *viewport = rt->getViewport();
     }
+    this->didBindFramebuffer();
 }
 
 void GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface) {
@@ -3394,6 +3397,19 @@
     }
 }
 
+void GrGLGpu::didBindFramebuffer() {
+    if (!this->caps()->workarounds().restore_scissor_on_fbo_change) {
+        return;
+    }
+
+    // The driver forgets the correct scissor when modifying the FBO binding.
+    fHWScissorSettings.fRect.pushToGLScissor(this->glInterface());
+
+    // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
+    // it's unclear how this bug works.
+    GL_CALL(Flush());
+}
+
 bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
                             GrSurface* src, GrSurfaceOrigin srcOrigin,
                             const SkIRect& srcRect, const SkIPoint& dstPoint,
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 43df889..d09dd4c 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -179,6 +179,8 @@
 
     void insertEventMarker(const char*);
 
+    void didBindFramebuffer();
+
 private:
     GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*);
 
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index e996588..693bc12 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -143,6 +143,8 @@
                                                           GR_GL_RENDERBUFFER, 0));
         }
 
+        gpu->didBindFramebuffer();
+
 #ifdef SK_DEBUG
         if (kChromium_GrGLDriver != gpu->glContext().driver()) {
             // This check can cause problems in Chromium if the context has been asynchronously