Include EXT_window_rectangles API

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2221393004

Review-Url: https://codereview.chromium.org/2221393004
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index c6b535d..924546f 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -264,6 +264,7 @@
         }
     }
 
+    int maxWindowRectangles() const { return fMaxWindowRectangles; }
 
     virtual bool isConfigTexturable(GrPixelConfig config) const = 0;
     virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0;
@@ -340,6 +341,7 @@
     int fMaxColorSampleCount;
     int fMaxStencilSampleCount;
     int fMaxRasterSamples;
+    int fMaxWindowRectangles;
 
 private:
     virtual void onApplyOptionsOverrides(const GrContextOptions&) {};
diff --git a/include/gpu/gl/GrGLFunctions.h b/include/gpu/gl/GrGLFunctions.h
index 7822eac..4dff208 100644
--- a/include/gpu/gl/GrGLFunctions.h
+++ b/include/gpu/gl/GrGLFunctions.h
@@ -353,6 +353,9 @@
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPopDebugGroupProc)();
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLObjectLabelProc)(GrGLenum identifier, GrGLuint name, GrGLsizei length, const GrGLchar *label);
 
+/** EXT_window_rectangles */
+typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLWindowRectanglesProc)(GrGLenum mode, GrGLsizei count, const GrGLint box[]);
+
 /** EGL functions */
 typedef const char* (GR_GL_FUNCTION_TYPE* GrEGLQueryStringProc)(GrEGLDisplay dpy, GrEGLint name);
 typedef GrEGLDisplay (GR_GL_FUNCTION_TYPE* GrEGLGetCurrentDisplayProc)();
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index b735b8f..0603e9e 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -460,6 +460,9 @@
         GrGLFunction<GrGLPopDebugGroupProc> fPopDebugGroup;
         GrGLFunction<GrGLObjectLabelProc> fObjectLabel;
 
+        /* EXT_window_rectangles */
+        GrGLFunction<GrGLWindowRectanglesProc> fWindowRectangles;
+
         /* EGL functions */
         GrGLFunction<GrEGLCreateImageProc> fEGLCreateImage;
         GrGLFunction<GrEGLDestroyImageProc> fEGLDestroyImage;
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 33c22be..19ef38c 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -118,6 +118,7 @@
     fMaxColorSampleCount = 0;
     fMaxStencilSampleCount = 0;
     fMaxRasterSamples = 0;
+    fMaxWindowRectangles = 0;
 
     fSuppressPrints = options.fSuppressPrints;
     fImmediateFlush = options.fImmediateMode;
@@ -197,6 +198,7 @@
     r.appendf("Max Color Sample Count             : %d\n", fMaxColorSampleCount);
     r.appendf("Max Stencil Sample Count           : %d\n", fMaxStencilSampleCount);
     r.appendf("Max Raster Samples                 : %d\n", fMaxRasterSamples);
+    r.appendf("Max Window Rectangles              : %d\n", fMaxWindowRectangles);
 
     static const char* kInstancedSupportNames[] = {
         "None",
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index 539d1ae..2233005 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -511,6 +511,10 @@
         GET_PROC(ObjectLabel);
     }
 
+    if (extensions.has("GL_EXT_window_rectangles")) {
+        GET_PROC_SUFFIX(WindowRectangles, EXT);
+    }
+
     if (extensions.has("EGL_KHR_image") || extensions.has("EGL_KHR_image_base")) {
         GET_EGL_PROC_SUFFIX(CreateImage, KHR);
         GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
@@ -897,6 +901,10 @@
         GET_PROC_SUFFIX(BindUniformLocation, CHROMIUM);
     }
 
+    if (extensions.has("GL_EXT_window_rectangles")) {
+        GET_PROC_SUFFIX(WindowRectangles, EXT);
+    }
+
     if (extensions.has("EGL_KHR_image") || extensions.has("EGL_KHR_image_base")) {
         GET_EGL_PROC_SUFFIX(CreateImage, KHR);
         GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index ea02d21..2c9990f 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -462,6 +462,12 @@
     }
     fMaxColorSampleCount = fMaxStencilSampleCount;
 
+    if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
+        GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
+        // Protect ourselves against tracking huge amounts of window rectangle state.
+        fMaxWindowRectangles = SkTMin(31, fMaxWindowRectangles);
+    }
+
     if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
         kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
         kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index 2fe22bd..8cd3751 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -962,6 +962,11 @@
 /* GL_ARB_texture_rectangle */
 #define GR_GL_TEXTURE_RECTANGLE                             0x84F5
 
+/* GL_EXT_window_rectangles */
+#define GR_GL_MAX_WINDOW_RECTANGLES                         0x8f14
+#define GR_GL_INCLUSIVE                                     0x8f10
+#define GR_GL_EXCLUSIVE                                     0x8f11
+
 /* EGL Defines */
 #define GR_EGL_NO_DISPLAY                                   ((GrEGLDisplay)0)
 #define GR_EGL_EXTENSIONS                                   0x3055
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index d11a86b..ada6d8b 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -769,6 +769,12 @@
         }
     }
 
+    if (fExtensions.has("GL_EXT_window_rectangles")) {
+        if (nullptr == fFunctions.fWindowRectangles) {
+            RETURN_FALSE_INTERFACE
+        }
+    }
+
     if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,0)) ||
         fExtensions.has("GL_ARB_sample_shading")) {
         if (nullptr == fFunctions.fMinSampleShading) {