1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
839edf7664f50b6c890b933b5bbed67a8735b349bjvanverth#include "GrGLGpu.h"
995e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary
1095e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "../private/GrGLSL.h"
1195e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "GrFixedClip.h"
12397536cabe12a9936659870dd220c869789424bacdalton#include "GrGLBuffer.h"
13066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrGLGpuCommandBuffer.h"
146be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel#include "GrGLSemaphore.h"
158dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel#include "GrGLStencilAttachment.h"
1637dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon#include "GrGLTextureRenderTarget.h"
173582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h"
180e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel#include "GrMesh.h"
1995e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "GrPipeline.h"
206bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTargetPriv.h"
2194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "GrShaderCaps.h"
22afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrSurfacePriv.h"
233798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips#include "GrSurfaceProxyPriv.h"
24afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrTexturePriv.h"
25ef3913bcbff265ff86116ae4f3dd2768dc42cccasenorblanco@chromium.org#include "GrTypes.h"
2695e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkAutoMalloc.h"
2718b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner#include "SkMakeUnique.h"
2855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkMipMap.h"
2955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkPixmap.h"
30c456b73fef9589bbdc5eb83eaa83e53c357bb3daKevin Lubick#include "SkSLCompiler.h"
3195e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkStrokeRec.h"
323582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com#include "SkTemplates.h"
3355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkTypes.h"
3495e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "builders/GrGLShaderStringBuilder.h"
3595e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "instanced/GLInstancedRendering.h"
36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
370b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
3856bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
390b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com
40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#define SKIP_CACHE_CHECK    true
41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
424f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com#if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
434f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com    #define CLEAR_ERROR_BEFORE_ALLOC(iface)   GrGLClearErr(iface)
444f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com    #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL_NOERRCHECK(iface, call)
454f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com    #define CHECK_ALLOC_ERROR(iface)          GR_GL_GET_ERROR(iface)
46fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com#else
474f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com    #define CLEAR_ERROR_BEFORE_ALLOC(iface)
484f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com    #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL(iface, call)
494f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com    #define CHECK_ALLOC_ERROR(iface)          GR_GL_NO_ERROR
504f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com#endif
514f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com
5232ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth//#define USE_NSIGHT
5332ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth
544bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com///////////////////////////////////////////////////////////////////////////////
554bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com
56a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonusing gr_instanced::InstancedRendering;
57a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonusing gr_instanced::GLInstancedRendering;
58b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
598917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonstatic const GrGLenum gXfermodeEquation2Blend[] = {
608917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    // Basic OpenGL blend equations.
618917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_FUNC_ADD,
628917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_FUNC_SUBTRACT,
638917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_FUNC_REVERSE_SUBTRACT,
648917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton
658917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    // GL_KHR_blend_equation_advanced.
668917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_SCREEN,
678917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_OVERLAY,
688917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_DARKEN,
698917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_LIGHTEN,
708917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_COLORDODGE,
718917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_COLORBURN,
728917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_HARDLIGHT,
738917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_SOFTLIGHT,
748917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_DIFFERENCE,
758917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_EXCLUSION,
768917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_MULTIPLY,
778917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_HSL_HUE,
788917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_HSL_SATURATION,
798917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_HSL_COLOR,
808917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GR_GL_HSL_LUMINOSITY
818917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton};
828917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(0 == kAdd_GrBlendEquation);
838917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation);
848917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation);
858917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(3 == kScreen_GrBlendEquation);
868917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(4 == kOverlay_GrBlendEquation);
878917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(5 == kDarken_GrBlendEquation);
888917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(6 == kLighten_GrBlendEquation);
898917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(7 == kColorDodge_GrBlendEquation);
908917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(8 == kColorBurn_GrBlendEquation);
918917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(9 == kHardLight_GrBlendEquation);
928917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(10 == kSoftLight_GrBlendEquation);
938917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(11 == kDifference_GrBlendEquation);
948917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(12 == kExclusion_GrBlendEquation);
958917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(13 == kMultiply_GrBlendEquation);
968917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(14 == kHSLHue_GrBlendEquation);
978917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(15 == kHSLSaturation_GrBlendEquation);
988917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(16 == kHSLColor_GrBlendEquation);
998917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdaltonGR_STATIC_ASSERT(17 == kHSLLuminosity_GrBlendEquation);
100f7cc87719e53df86784d0d953b88c45a3be38953bsalomonGR_STATIC_ASSERT(SK_ARRAY_COUNT(gXfermodeEquation2Blend) == kGrBlendEquationCnt);
1018917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton
1020f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.comstatic const GrGLenum gXfermodeCoeff2Blend[] = {
1030f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ZERO,
1040f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ONE,
1050f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_SRC_COLOR,
1060f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ONE_MINUS_SRC_COLOR,
1070f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_DST_COLOR,
1080f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ONE_MINUS_DST_COLOR,
1090f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_SRC_ALPHA,
1100f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ONE_MINUS_SRC_ALPHA,
1110f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_DST_ALPHA,
1120f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ONE_MINUS_DST_ALPHA,
1130f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_CONSTANT_COLOR,
1140f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ONE_MINUS_CONSTANT_COLOR,
1150f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_CONSTANT_ALPHA,
1160f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_ONE_MINUS_CONSTANT_ALPHA,
117271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com
118271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    // extended blend coeffs
119271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    GR_GL_SRC1_COLOR,
120271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    GR_GL_ONE_MINUS_SRC1_COLOR,
121271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    GR_GL_SRC1_ALPHA,
122271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    GR_GL_ONE_MINUS_SRC1_ALPHA,
123ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com};
124ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
125861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonbool GrGLGpu::BlendCoeffReferencesConstant(GrBlendCoeff coeff) {
126080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com    static const bool gCoeffReferencesBlendConst[] = {
127080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
128080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
129080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
130080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
131080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
132080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
133080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
134080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
135080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
136080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        false,
137080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        true,
138080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        true,
139080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        true,
140080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com        true,
141271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com
142271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        // extended blend coeffs
143271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        false,
144271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        false,
145271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        false,
146271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        false,
147080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com    };
148080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com    return gCoeffReferencesBlendConst[coeff];
149f7cc87719e53df86784d0d953b88c45a3be38953bsalomon    GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendConst));
15047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com
15147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff);
15247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff);
15347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff);
15447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff);
15547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff);
15647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff);
15747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff);
15847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff);
15947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff);
16047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff);
16147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff);
16247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff);
16347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff);
16447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff);
16547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com
16647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff);
16747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff);
16847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff);
16947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com    GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff);
170271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com
171271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope
172f7cc87719e53df86784d0d953b88c45a3be38953bsalomon    GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gXfermodeCoeff2Blend));
173080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com}
174080773ca79cbdc230730d295441255e9254d76a6bsalomon@google.com
175ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com///////////////////////////////////////////////////////////////////////////////
176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
177ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
178682c269a1511200322916af83053e26004c0ec40bsalomonGrGpu* GrGLGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
179682c269a1511200322916af83053e26004c0ec40bsalomon                       GrContext* context) {
180144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    sk_sp<const GrGLInterface> glInterface(
181424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon        reinterpret_cast<const GrGLInterface*>(backendContext));
182424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    if (!glInterface) {
183424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon        glInterface.reset(GrGLDefaultInterface());
184424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    } else {
185424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon        glInterface->ref();
186424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    }
187424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    if (!glInterface) {
18896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
189424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    }
190144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    GrGLContext* glContext = GrGLContext::Create(glInterface.get(), options);
191424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    if (glContext) {
192385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        return new GrGLGpu(glContext, context);
193424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    }
19496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
195424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon}
196424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon
197e38160c38c295a4d9cd2441727ebdc6e5f47e225rileya@google.comstatic bool gPrintStartupSpew;
19842ab7ea76e57ae1abaf98258ecd159f60c36b3babsalomon@google.com
199424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomonGrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
2006e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    : GrGpu(context)
201e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    , fGLContext(ctx)
202e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    , fProgramCache(new ProgramCache(this))
203e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    , fHWProgramID(0)
204e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    , fTempSrcFBOID(0)
205e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    , fTempDstFBOID(0)
206e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    , fStencilClearFBOID(0)
20774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    , fHWMaxUsedBufferTextureUnit(-1)
208e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    , fHWMinSampleShading(0.0) {
209e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
210e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fCopyPrograms[i].fProgram = 0;
211e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
21233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
21333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        fMipmapPrograms[i].fProgram = 0;
21433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
215e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fWireRectProgram.fProgram = 0;
216e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
217424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    SkASSERT(ctx);
218424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    fCaps.reset(SkRef(ctx->caps()));
219bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
2201edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    fHWBoundTextureUniqueIDs.reset(this->caps()->shaderCaps()->maxCombinedSamplers());
2211edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    fHWBoundImageStorages.reset(this->caps()->shaderCaps()->maxCombinedImageStorages());
222a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org
223e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER;
224e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER;
225e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fHWBufferState[kTexel_GrBufferType].fGLTarget = GR_GL_TEXTURE_BUFFER;
226e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fHWBufferState[kDrawIndirect_GrBufferType].fGLTarget = GR_GL_DRAW_INDIRECT_BUFFER;
227e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (GrGLCaps::kChromium_TransferBufferType == this->glCaps().transferBufferType()) {
228e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget =
229e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM;
230e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget =
231e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
232e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    } else {
233e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = GR_GL_PIXEL_UNPACK_BUFFER;
234e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = GR_GL_PIXEL_PACK_BUFFER;
235e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
236e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState));
237e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
23874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    if (this->caps()->shaderCaps()->texelBufferSupport()) {
2391edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        fHWBufferTextures.reset(this->caps()->shaderCaps()->maxCombinedSamplers());
24074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    }
24174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
242e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
243e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fPathRendering.reset(new GrGLPathRendering(this));
244e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
245e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
246424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon    GrGLClearErr(this->glInterface());
247eeeb5a05b900df80feded719b4a3181fce0ac1b4reed@google.com    if (gPrintStartupSpew) {
24856bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com        const GrGLubyte* vendor;
24956bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com        const GrGLubyte* renderer;
25056bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com        const GrGLubyte* version;
25156bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com        GL_CALL_RET(vendor, GetString(GR_GL_VENDOR));
25256bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com        GL_CALL_RET(renderer, GetString(GR_GL_RENDERER));
25356bfc5acc210987838744eece7383bc2f6b34915bsalomon@google.com        GL_CALL_RET(version, GetString(GR_GL_VERSION));
254861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon        SkDebugf("------------------------- create GrGLGpu %p --------------\n",
255eeeb5a05b900df80feded719b4a3181fce0ac1b4reed@google.com                 this);
25638406c82b913350e55fa04af8c1941cd9b4aff52tfarina        SkDebugf("------ VENDOR %s\n", vendor);
25738406c82b913350e55fa04af8c1941cd9b4aff52tfarina        SkDebugf("------ RENDERER %s\n", renderer);
25838406c82b913350e55fa04af8c1941cd9b4aff52tfarina        SkDebugf("------ VERSION %s\n",  version);
25938406c82b913350e55fa04af8c1941cd9b4aff52tfarina        SkDebugf("------ EXTENSIONS\n");
260424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon        this->glContext().extensions().print();
26138406c82b913350e55fa04af8c1941cd9b4aff52tfarina        SkDebugf("\n");
262297aaf97a32ac16a2bc3f4bbc231d5de859ac02dkkinnunen        SkDebugf("%s", this->glCaps().dump().c_str());
263eeeb5a05b900df80feded719b4a3181fce0ac1b4reed@google.com    }
26418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com}
26518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com
266861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonGrGLGpu::~GrGLGpu() {
267e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    // Ensure any GrGpuResource objects get deleted first, since they may require a working GrGLGpu
268e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    // to release the resources held by the objects themselves.
269702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    fPathRendering.reset();
270e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fCopyProgramArrayBuffer.reset();
27133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    fMipmapProgramArrayBuffer.reset();
272e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fWireRectArrayBuffer.reset();
273702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen
2749ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com    if (0 != fHWProgramID) {
2755739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com        // detach the current program so there is no confusion on OpenGL's part
2765739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com        // that we want it to be deleted
2775739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com        GL_CALL(UseProgram(0));
2785739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com    }
2795739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com
280d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (0 != fTempSrcFBOID) {
281d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
2820f5f967f6777612353c762e6d0095f733adfb326egdaniel    }
283d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (0 != fTempDstFBOID) {
284d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
2850f5f967f6777612353c762e6d0095f733adfb326egdaniel    }
286d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (0 != fStencilClearFBOID) {
287d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
288dd3143b0079f01980ca4886f00c39b3caa3fee6absalomon    }
2890f5f967f6777612353c762e6d0095f733adfb326egdaniel
2907ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
2917ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        if (0 != fCopyPrograms[i].fProgram) {
2927ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon            GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
2937ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        }
2946df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    }
2956dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
29633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
29733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        if (0 != fMipmapPrograms[i].fProgram) {
29833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram));
29933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
30033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
30133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
3026dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    if (0 != fWireRectProgram.fProgram) {
3036dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
3046dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    }
3056dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
306c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com    delete fProgramCache;
307c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon}
308c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon
3096e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomonvoid GrGLGpu::disconnect(DisconnectType type) {
3106e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    INHERITED::disconnect(type);
3116e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    if (DisconnectType::kCleanup == type) {
3126e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        if (fHWProgramID) {
3136e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            GL_CALL(UseProgram(0));
3146e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        }
3156e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        if (fTempSrcFBOID) {
3166e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
3176e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        }
3186e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        if (fTempDstFBOID) {
3196e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
3206e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        }
3216e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        if (fStencilClearFBOID) {
3226e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
3236e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        }
3246e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
3256e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            if (fCopyPrograms[i].fProgram) {
3266e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon                GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
3276e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            }
3286e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        }
32933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
33033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            if (fMipmapPrograms[i].fProgram) {
33133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram));
33233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            }
33333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
3346e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        if (fWireRectProgram.fProgram) {
3356e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
3366e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        }
3376e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    } else {
3386e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        if (fProgramCache) {
3396e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon            fProgramCache->abandon();
3406e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        }
3416e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    }
3426e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
3436e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    delete fProgramCache;
3446e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    fProgramCache = nullptr;
3456e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
346c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    fHWProgramID = 0;
347d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    fTempSrcFBOID = 0;
348d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    fTempDstFBOID = 0;
349d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    fStencilClearFBOID = 0;
350e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fCopyProgramArrayBuffer.reset();
3517ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
3527ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        fCopyPrograms[i].fProgram = 0;
3537ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
35433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    fMipmapProgramArrayBuffer.reset();
35533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
35633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        fMipmapPrograms[i].fProgram = 0;
35733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
3586dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    fWireRectProgram.fProgram = 0;
359e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fWireRectArrayBuffer.reset();
360e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth    if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
3616e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon        this->glPathRendering()->disconnect(type);
362c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    }
36318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com}
36418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com
36518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
366a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com
367861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::onResetContext(uint32_t resetBits) {
3685aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com    // we don't use the zb at all
3690a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kMisc_GrGLBackendState) {
3700a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        GL_CALL(Disable(GR_GL_DEPTH_TEST));
3710a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        GL_CALL(DepthMask(GR_GL_FALSE));
3720a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com
373e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kTexel_GrBufferType].invalidate();
374e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kDrawIndirect_GrBufferType].invalidate();
375e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kXferCpuToGpu_GrBufferType].invalidate();
376e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kXferGpuToCpu_GrBufferType].invalidate();
377c161310ffdbbcb3b023da2e375faefd211fa52e8cdalton
3785fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips        fHWDrawFace = GrDrawFace::kInvalid;
3799e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org        if (kGL_GrGLStandard == this->glStandard()) {
38032ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#ifndef USE_NSIGHT
3810a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // Desktop-only state that we never change
3820a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            if (!this->glCaps().isCoreProfile()) {
3830a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com                GL_CALL(Disable(GR_GL_POINT_SMOOTH));
3840a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com                GL_CALL(Disable(GR_GL_LINE_SMOOTH));
3850a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com                GL_CALL(Disable(GR_GL_POLYGON_SMOOTH));
3860a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com                GL_CALL(Disable(GR_GL_POLYGON_STIPPLE));
3870a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com                GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP));
3880a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com                GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP));
3890a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            }
3900a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a
3910a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // core profile. This seems like a bug since the core spec removes any mention of
3920a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // GL_ARB_imaging.
3930a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) {
3940a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com                GL_CALL(Disable(GR_GL_COLOR_TABLE));
3950a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            }
3960a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL));
39732ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#endif
3980a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // Since ES doesn't support glPointSize at all we always use the VS to
3990a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // set the point size
4000a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE));
4010a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com
4020a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // We should set glPolygonMode(FRONT_AND_BACK,FILL) here, too. It isn't
4030a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // currently part of our gl interface. There are probably others as
4040a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            // well.
405ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com        }
4065816233d237e5c214f14f1c92eda4a87c898ea11joshualitt
4075816233d237e5c214f14f1c92eda4a87c898ea11joshualitt        if (kGLES_GrGLStandard == this->glStandard() &&
408424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon                this->hasExtension("GL_ARM_shader_framebuffer_fetch")) {
4095816233d237e5c214f14f1c92eda4a87c898ea11joshualitt            // The arm extension requires specifically enabling MSAA fetching per sample.
4105816233d237e5c214f14f1c92eda4a87c898ea11joshualitt            // On some devices this may have a perf hit.  Also multiple render targets are disabled
4115816233d237e5c214f14f1c92eda4a87c898ea11joshualitt            GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
4125816233d237e5c214f14f1c92eda4a87c898ea11joshualitt        }
4130a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        fHWWriteToColor = kUnknown_TriState;
4140a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        // we only ever use lines in hairline mode
4150a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        GL_CALL(LineWidth(1));
416aca31fea8ca620bfdb2887641b7ba56e401a72d7bsalomon        GL_CALL(Disable(GR_GL_DITHER));
417b65e0cb8ad8a690498142d2b0097be250b0c7dfbtwiz@google.com    }
418d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
419b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel    if (resetBits & kMSAAEnable_GrGLBackendState) {
420b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel        fMSAAEnabled = kUnknown_TriState;
421dded69693dd3779f081326cde24c3954505b129dvbuzinov
422eed519e6a2d0e61b0733a388de9320af897ed197egdaniel        if (this->caps()->usesMixedSamples()) {
423af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            if (0 != this->caps()->maxRasterSamples()) {
424af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                fHWRasterMultisampleEnabled = kUnknown_TriState;
425af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                fHWNumRasterSamples = 0;
426af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            }
427af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton
428af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            // The skia blend modes all use premultiplied alpha and therefore expect RGBA coverage
429af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            // modulation. This state has no effect when not rendering to a mixed sampled target.
430dded69693dd3779f081326cde24c3954505b129dvbuzinov            GL_CALL(CoverageModulation(GR_GL_RGBA));
431dded69693dd3779f081326cde24c3954505b129dvbuzinov        }
4320a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    }
433ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
43446fbfe0cd1bbe60fd15ce52e784f5d51450ff5fdcommit-bot@chromium.org    fHWActiveTextureUnitIdx = -1; // invalid
43546fbfe0cd1bbe60fd15ce52e784f5d51450ff5fdcommit-bot@chromium.org
4360a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kTextureBinding_GrGLBackendState) {
4371c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon        for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) {
438294870ff119b89fc902773643b054f14e5d1f554Robert Phillips            fHWBoundTextureUniqueIDs[s].makeInvalid();
4390a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        }
44074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        for (int b = 0; b < fHWBufferTextures.count(); ++b) {
44174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            SkASSERT(this->caps()->shaderCaps()->texelBufferSupport());
44274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            fHWBufferTextures[b].fKnownBound = false;
44374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        }
444f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon        for (int i = 0; i < fHWBoundImageStorages.count(); ++i) {
4458b7a7ddea344eed96f095652359c5c86349f86d0Brian Salomon            SkASSERT(this->caps()->shaderCaps()->imageLoadStoreSupport());
446f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon            fHWBoundImageStorages[i].fTextureUniqueID.makeInvalid();
447f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon        }
448cad107bbe723e5e71e625dccb5d7bcfe20c55c58bsalomon@google.com    }
449ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4500a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kBlend_GrGLBackendState) {
4510a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        fHWBlendState.invalidate();
4520a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    }
453730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com
4540a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kView_GrGLBackendState) {
4550a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        fHWScissorSettings.invalidate();
456bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton        fHWWindowRectsState.invalidate();
4570a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        fHWViewport.invalidate();
4580a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    }
459ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4600a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kStencil_GrGLBackendState) {
4610a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        fHWStencilSettings.invalidate();
4620a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        fHWStencilTestEnabled = kUnknown_TriState;
4630a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    }
4648ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com
4650a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    // Vertex
4660a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kVertex_GrGLBackendState) {
467e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWVertexArrayState.invalidate();
468e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kVertex_GrBufferType].invalidate();
469e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fHWBufferState[kIndex_GrBufferType].invalidate();
4700a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    }
471ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com
4720a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kRenderTarget_GrGLBackendState) {
473294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        fHWBoundRenderTargetUniqueID.makeInvalid();
47416921ec30a81976129d507b1148c93a322e61a4fbsalomon        fHWSRGBFramebuffer = kUnknown_TriState;
4750a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    }
476ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com
4770a6fe71f1bc0e601b41b7ae6d28b8c96a2c41116commit-bot@chromium.org    if (resetBits & kPathRendering_GrGLBackendState) {
478e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth        if (this->caps()->shaderCaps()->pathRenderingSupport()) {
479ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            this->glPathRendering()->resetContext();
4800a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        }
48105a718c9d2302b08f859adac5854b2df6ff84e43bsalomon@google.com    }
482ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com
4838ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com    // we assume these values
4840a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kPixelStore_GrGLBackendState) {
4850a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        if (this->glCaps().unpackRowLengthSupport()) {
4860a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
4870a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        }
4880a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        if (this->glCaps().packRowLengthSupport()) {
4890a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
4900a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        }
4910a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        if (this->glCaps().unpackFlipYSupport()) {
4920a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
4930a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        }
4940a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        if (this->glCaps().packFlipYSupport()) {
4950a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com            GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
4960a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        }
497ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com    }
498ba669991e539211785ce3b958cc4dd8705f98c9eedisonn@google.com
4990a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    if (resetBits & kProgram_GrGLBackendState) {
5000a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com        fHWProgramID = 0;
5010a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    }
502ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
503ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
504cf614fd48e38f7c544e666dd19a5a81c35830ba3egdanielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin, bool renderTarget) {
5053cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    // By default, GrRenderTargets are GL's normal orientation so that they
5063cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    // can be drawn to by the outside world without the client having
5073cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    // to render upside down.
5083cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    if (kDefault_GrSurfaceOrigin == origin) {
5093cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org        return renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
5103cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    } else {
5113cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org        return origin;
5123cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    }
5133cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org}
5143cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org
5156bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
5166bd5284415bd983b0628c4941dff5def40018f5abungeman                                               GrWrapOwnership ownership) {
517091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    const GrGLTextureInfo* info = reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle);
518091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    if (!info || !info->fID) {
51996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
520b72e5d31383464171c01370c09cdbba77707e8efrobertphillips@google.com    }
521b72e5d31383464171c01370c09cdbba77707e8efrobertphillips@google.com
5227ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    // next line relies on GrBackendTextureDesc's flags matching GrTexture's
5237ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
524766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman    SkASSERT(!renderTarget || kAdoptAndCache_GrWrapOwnership != ownership);  // Not supported
5257ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
526b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    GrGLTexture::IDDesc idDesc;
527091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    idDesc.fInfo = *info;
528e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon
5297ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (GR_GL_TEXTURE_EXTERNAL == idDesc.fInfo.fTarget) {
5307ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        if (renderTarget) {
5317ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon            // This combination is not supported.
5327ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon            return nullptr;
5337ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        }
5341edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        if (!this->caps()->shaderCaps()->externalTextureSupport()) {
5357ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon            return nullptr;
5367ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        }
537e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    } else  if (GR_GL_TEXTURE_RECTANGLE == idDesc.fInfo.fTarget) {
538e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        if (!this->glCaps().rectangleTextureSupport()) {
539e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon            return nullptr;
540e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        }
541e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    } else if (GR_GL_TEXTURE_2D != idDesc.fInfo.fTarget) {
542e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        return nullptr;
5437ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
544e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon
545e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    // Sample count is interpreted to mean the number of samples that Gr code should allocate
546a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon    // for a render buffer that resolves to the texture. We don't support MSAA textures.
547a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon    if (desc.fSampleCnt && !renderTarget) {
548a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon        return nullptr;
549a98419be092cce2a7ef27a09b6fd8065ff709cffbsalomon    }
55010528f1d5838ae1cac015024c4e8731484f888d1bsalomon
551766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman    if (kBorrow_GrWrapOwnership == ownership) {
552a6953f2a079a64848499709b9c635405f53566e3Brian Osman        idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed;
553766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman    } else {
554766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman        idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
555e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    }
556b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon
55718b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner    GrSurfaceDesc surfDesc;
558b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
559b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    surfDesc.fWidth = desc.fWidth;
560b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    surfDesc.fHeight = desc.fHeight;
561b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    surfDesc.fConfig = desc.fConfig;
56294e50100eb747b2dfd659bacc9cf4246f6f20278senorblanco    surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount());
5633cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    // FIXME:  this should be calling resolve_origin(), but Chrome code is currently
5643cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    // assuming the old behaviour, which is that backend textures are always
5653cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    // BottomLeft, even for non-RT's.  Once Chrome is fixed, change this to:
5663cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
5673cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    if (kDefault_GrSurfaceOrigin == desc.fOrigin) {
568b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
5693cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    } else {
570b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        surfDesc.fOrigin = desc.fOrigin;
5713cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    }
572e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com
5733cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    if (renderTarget) {
574b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        GrGLRenderTarget::IDDesc rtIDDesc;
5752e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen        if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) {
57696fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
577e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com        }
5786bd5284415bd983b0628c4941dff5def40018f5abungeman        return GrGLTextureRenderTarget::MakeWrapped(this, surfDesc, idDesc, rtIDDesc);
579e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    }
580766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman
581766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman    if (kAdoptAndCache_GrWrapOwnership == ownership) {
582766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman        return sk_sp<GrTexture>(new GrGLTexture(this, SkBudgeted::kYes, surfDesc, idDesc));
583766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman    } else {
584766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman        return GrGLTexture::MakeWrapped(this, surfDesc, idDesc);
585766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman    }
586e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com}
587e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com
5880b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osmansk_sp<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc){
589b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    GrGLRenderTarget::IDDesc idDesc;
590d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle);
591b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    idDesc.fMSColorRenderbufferID = 0;
592d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
5930b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman    idDesc.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed;
594f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton    idDesc.fIsMixedSampled = false;
595b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon
596b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    GrSurfaceDesc desc;
597b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    desc.fConfig = wrapDesc.fConfig;
5984b013296bf67df6c8d119a8f5a2b3dd6530c0b6fsenorblanco    desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag;
599b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    desc.fWidth = wrapDesc.fWidth;
600b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    desc.fHeight = wrapDesc.fHeight;
60194e50100eb747b2dfd659bacc9cf4246f6f20278senorblanco    desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount());
602b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true);
603b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon
6046bd5284415bd983b0628c4941dff5def40018f5abungeman    return GrGLRenderTarget::MakeWrapped(this, desc, idDesc, wrapDesc.fStencilBits);
605e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com}
606e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com
6076bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc){
608f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    const GrGLTextureInfo* info = reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle);
609f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    if (!info || !info->fID) {
610f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        return nullptr;
611f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    }
612f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk
613db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth    GrGLTextureInfo texInfo;
614db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth    texInfo = *info;
615f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk
616db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth    if (GR_GL_TEXTURE_RECTANGLE != texInfo.fTarget &&
617db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth        GR_GL_TEXTURE_2D != texInfo.fTarget) {
618f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        // Only texture rectangle and texture 2d are supported. We do not check whether texture
619f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        // rectangle is supported by Skia - if the caller provided us with a texture rectangle,
620f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        // we assume the necessary support exists.
621f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        return nullptr;
622f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    }
623f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk
62418b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner    GrSurfaceDesc surfDesc;
625f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
626f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    surfDesc.fWidth = desc.fWidth;
627f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    surfDesc.fHeight = desc.fHeight;
628f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    surfDesc.fConfig = desc.fConfig;
629f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount());
630f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    // FIXME:  this should be calling resolve_origin(), but Chrome code is currently
631f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    // assuming the old behaviour, which is that backend textures are always
632f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    // BottomLeft, even for non-RT's.  Once Chrome is fixed, change this to:
633f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
634f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    if (kDefault_GrSurfaceOrigin == desc.fOrigin) {
635f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
636f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    } else {
637f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        surfDesc.fOrigin = desc.fOrigin;
638f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    }
639f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk
640f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    GrGLRenderTarget::IDDesc rtIDDesc;
641db1adf59890dfd50212ac217eaa2d04e70c0d37cjvanverth    if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) {
642f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk        return nullptr;
643f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk    }
6446bd5284415bd983b0628c4941dff5def40018f5abungeman    return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0);
645f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk}
646f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk
64771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
648f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk
649f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomonbool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
650ed828001da75f4a3a5d31d9f1c1935e3595ce920cblume                                   GrPixelConfig srcConfig,
651f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                                   DrawPreference* drawPreference,
652f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                                   WritePixelTempDrawInfo* tempDrawInfo) {
653d0be1ef36c64c2a420cbd82f4c033704d4c54a07Brian Osman    if (GrPixelConfigIsCompressed(dstSurface->config())) {
654f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        return false;
655f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    }
656f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon
6576cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    // This subclass only allows writes to textures. If the dst is not a texture we have to draw
6586cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    // into it. We could use glDrawPixels on GLs that have it, but we don't today.
6596cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    if (!dstSurface->asTexture()) {
6606cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
6617ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    } else {
6627ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        GrGLTexture* texture = static_cast<GrGLTexture*>(dstSurface->asTexture());
663e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        if (GR_GL_TEXTURE_EXTERNAL == texture->target()) {
664e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon             // We don't currently support writing pixels to EXTERNAL textures.
6657ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon             return false;
6667ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        }
6676cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    }
6686cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon
66916921ec30a81976129d507b1148c93a322e61a4fbsalomon    if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConfig)) {
67016921ec30a81976129d507b1148c93a322e61a4fbsalomon        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
67116921ec30a81976129d507b1148c93a322e61a4fbsalomon    }
67216921ec30a81976129d507b1148c93a322e61a4fbsalomon
6736c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon    // Start off assuming no swizzling
6746c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
6756c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon    tempDrawInfo->fWriteConfig = srcConfig;
676f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon
677f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    // These settings we will always want if a temp draw is performed. Initially set the config
678f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    // to srcConfig, though that may be modified if we decide to do a R/G swap.
679f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
680f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
681f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
682f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
683f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
684f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
685f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon
686f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
687f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon
688f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    if (configsAreRBSwaps) {
689f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        if (!this->caps()->isConfigTexturable(srcConfig)) {
690f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
691f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
6926c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
6936c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon            tempDrawInfo->fWriteConfig = dstSurface->config();
69488c7b988ba7792e51e741567426069cd9cc852ddbsalomon        } else if (this->glCaps().rgba8888PixelsOpsAreSlow() &&
69588c7b988ba7792e51e741567426069cd9cc852ddbsalomon                   kRGBA_8888_GrPixelConfig == srcConfig) {
696f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
697f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
6986c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
6996c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon            tempDrawInfo->fWriteConfig = dstSurface->config();
700f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        } else if (kGLES_GrGLStandard == this->glStandard() &&
701f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                   this->glCaps().bgraIsInternalFormat()) {
702f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            // The internal format and external formats must match texture uploads so we can't
703f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            // swizzle while uploading when BGRA is a distinct internal format.
704f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
705f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
7066c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
7076c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon            tempDrawInfo->fWriteConfig = dstSurface->config();
708f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        }
709f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    }
710f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon
711f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    if (!this->glCaps().unpackFlipYSupport() &&
712f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) {
713f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
714f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    }
715f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon
716f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    return true;
717f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon}
71871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com
71917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverthstatic bool check_write_and_transfer_input(GrGLTexture* glTex, GrSurface* surface,
72017aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth                                            GrPixelConfig config) {
7216cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    if (!glTex) {
7226cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon        return false;
7236cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    }
724280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com
72516921ec30a81976129d507b1148c93a322e61a4fbsalomon    // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
72616921ec30a81976129d507b1148c93a322e61a4fbsalomon    if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
72716921ec30a81976129d507b1148c93a322e61a4fbsalomon        return false;
72816921ec30a81976129d507b1148c93a322e61a4fbsalomon    }
72916921ec30a81976129d507b1148c93a322e61a4fbsalomon
730e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textures
731e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) {
7327ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return false;
7337ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
7347ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
73517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    return true;
73617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth}
73717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
73817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverthbool GrGLGpu::onWritePixels(GrSurface* surface,
73917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth                            int left, int top, int width, int height,
74055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                            GrPixelConfig config,
74155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                            const SkTArray<GrMipLevel>& texels) {
74217aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
74317aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
74417aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    if (!check_write_and_transfer_input(glTex, surface, config)) {
74517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth        return false;
74617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    }
74717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
748a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org    this->setScratchTextureUnit();
74910528f1d5838ae1cac015024c4e8731484f888d1bsalomon    GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
7506f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
751145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    bool success = false;
752b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
753861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon        // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixels()
754b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        SkASSERT(config == glTex->desc().fConfig);
75555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), texels,
75617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth                                                kWrite_UploadType, left, top, width, height);
757145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    } else {
758e7d7f90b59b15a291c113b449f5c6ac57f8d1aacjcgregorio        success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_UploadType,
75955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                      left, top, width, height, config, texels);
760cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org    }
761145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski
76255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    return success;
7636f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com}
7649d6cfd80a06e5efde1fc865c5e65c0ad27389a3fbsalomon@google.com
765c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverthbool GrGLGpu::onTransferPixels(GrSurface* surface,
76617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth                               int left, int top, int width, int height,
767397536cabe12a9936659870dd220c869789424bacdalton                               GrPixelConfig config, GrBuffer* transferBuffer,
76817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth                               size_t offset, size_t rowBytes) {
769c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth    GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
77017aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
771c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth    if (!check_write_and_transfer_input(glTex, surface, config)) {
77217aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth        return false;
77317aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    }
77417aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
77517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    // For the moment, can't transfer compressed data
77617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
77717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth        return false;
77817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    }
77917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
78017aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    this->setScratchTextureUnit();
78117aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
78217aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
783397536cabe12a9936659870dd220c869789424bacdalton    SkASSERT(!transferBuffer->isMapped());
784397536cabe12a9936659870dd220c869789424bacdalton    SkASSERT(!transferBuffer->isCPUBacked());
785397536cabe12a9936659870dd220c869789424bacdalton    const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer);
786e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer);
78717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
78817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    bool success = false;
78955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GrMipLevel mipLevel;
790c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth    mipLevel.fPixels = transferBuffer;
79155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    mipLevel.fRowBytes = rowBytes;
79255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkSTArray<1, GrMipLevel> texels;
79355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    texels.push_back(mipLevel);
794e7d7f90b59b15a291c113b449f5c6ac57f8d1aacjcgregorio    success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_UploadType,
79555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                  left, top, width, height, config, texels);
796900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    return success;
79717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth}
79817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth
799f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon// For GL_[UN]PACK_ALIGNMENT.
800f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomonstatic inline GrGLint config_alignment(GrPixelConfig config) {
801f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon    SkASSERT(!GrPixelConfigIsCompressed(config));
802f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon    switch (config) {
803f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kAlpha_8_GrPixelConfig:
804986563bcff26300ea4317b4dd84917d5240bb723Brian Osman        case kGray_8_GrPixelConfig:
805f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon            return 1;
806f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kRGB_565_GrPixelConfig:
807f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kRGBA_4444_GrPixelConfig:
808f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kAlpha_half_GrPixelConfig:
809f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kRGBA_half_GrPixelConfig:
810f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon            return 2;
811f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kRGBA_8888_GrPixelConfig:
812f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kBGRA_8888_GrPixelConfig:
813f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kSRGBA_8888_GrPixelConfig:
814a6359365887048ef055196de75591311d7a015f0brianosman        case kSBGRA_8888_GrPixelConfig:
815bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        case kRGBA_8888_sint_GrPixelConfig:
816f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon        case kRGBA_float_GrPixelConfig:
8176aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton        case kRG_float_GrPixelConfig:
818f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon            return 4;
8196aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton        case kUnknown_GrPixelConfig:
8206aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton        case kETC1_GrPixelConfig:
821f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon            return 0;
822f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon    }
8236aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton    SkFAIL("Invalid pixel config");
8246aa0e1150ecf7eb5462744a32c356a0006d63c9ecsmartdalton    return 0;
825f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon}
826f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon
827b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomonstatic inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
828b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon                                         const GrGLInterface* interface) {
829f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) {
830d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org        return GR_GL_GET_ERROR(interface);
831d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org    } else {
832d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org        return CHECK_ALLOC_ERROR(interface);
833d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org    }
834d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org}
835d0925240efb3732475e62966896716c28e9902b2senorblanco@chromium.org
83655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume/**
83755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * Creates storage space for the texture and fills it with texels.
83855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume *
83955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param desc           The surface descriptor for the texture being created.
84055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param interface      The GL interface in use.
841790d5132620d86813380d3df251e80dd2b41a409cblume * @param caps           The capabilities of the GL device.
84281a8485997162a6f2bef84b1130033b1222c722cbrianosman * @param internalFormat The data format used for the internal storage of the texture. May be sized.
84381a8485997162a6f2bef84b1130033b1222c722cbrianosman * @param internalFormatForTexStorage The data format used for the TexStorage API. Must be sized.
84455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param externalFormat The data format used for the external storage of the texture.
84555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param externalType   The type of the data used for the external storage of the texture.
84655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param texels         The texel data of the texture being created.
84755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param baseWidth      The width of the texture's base mipmap level
84855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param baseHeight     The height of the texture's base mipmap level
84955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param succeeded      Set to true if allocating and populating the texture completed
85055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume *                       without error.
85155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume */
852e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomonstatic bool allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc,
85355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                       const GrGLInterface& interface,
854790d5132620d86813380d3df251e80dd2b41a409cblume                                                       const GrGLCaps& caps,
85555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                       GrGLenum target,
85655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                       GrGLenum internalFormat,
85781a8485997162a6f2bef84b1130033b1222c722cbrianosman                                                       GrGLenum internalFormatForTexStorage,
85855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                       GrGLenum externalFormat,
85955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                       GrGLenum externalType,
86055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                       const SkTArray<GrMipLevel>& texels,
861e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                                       int baseWidth, int baseHeight) {
86255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    CLEAR_ERROR_BEFORE_ALLOC(&interface);
863790d5132620d86813380d3df251e80dd2b41a409cblume
864790d5132620d86813380d3df251e80dd2b41a409cblume    bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig);
865790d5132620d86813380d3df251e80dd2b41a409cblume    // We can only use TexStorage if we know we will not later change the storage requirements.
866790d5132620d86813380d3df251e80dd2b41a409cblume    // This means if we may later want to add mipmaps, we cannot use TexStorage.
867790d5132620d86813380d3df251e80dd2b41a409cblume    // Right now, we cannot know if we will later add mipmaps or not.
868790d5132620d86813380d3df251e80dd2b41a409cblume    // The only time we can use TexStorage is when we already have the
869bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // mipmaps or are using a format incompatible with MIP maps.
870bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    useTexStorage &= texels.count() > 1 || GrPixelConfigIsSint(desc.fConfig);
871790d5132620d86813380d3df251e80dd2b41a409cblume
872790d5132620d86813380d3df251e80dd2b41a409cblume    if (useTexStorage) {
873790d5132620d86813380d3df251e80dd2b41a409cblume        // We never resize or change formats of textures.
87455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GL_ALLOC_CALL(&interface,
875790d5132620d86813380d3df251e80dd2b41a409cblume                      TexStorage2D(target,
876bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon                                   SkTMax(texels.count(), 1),
87781a8485997162a6f2bef84b1130033b1222c722cbrianosman                                   internalFormatForTexStorage,
878790d5132620d86813380d3df251e80dd2b41a409cblume                                   desc.fWidth, desc.fHeight));
87955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GrGLenum error = check_alloc_error(desc, &interface);
88055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        if (error != GR_GL_NO_ERROR) {
881e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon            return  false;
882790d5132620d86813380d3df251e80dd2b41a409cblume        } else {
883790d5132620d86813380d3df251e80dd2b41a409cblume            for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
884790d5132620d86813380d3df251e80dd2b41a409cblume                const void* currentMipData = texels[currentMipLevel].fPixels;
885790d5132620d86813380d3df251e80dd2b41a409cblume                if (currentMipData == nullptr) {
886790d5132620d86813380d3df251e80dd2b41a409cblume                    continue;
887790d5132620d86813380d3df251e80dd2b41a409cblume                }
888790d5132620d86813380d3df251e80dd2b41a409cblume                int twoToTheMipLevel = 1 << currentMipLevel;
889790d5132620d86813380d3df251e80dd2b41a409cblume                int currentWidth = SkTMax(1, desc.fWidth / twoToTheMipLevel);
890790d5132620d86813380d3df251e80dd2b41a409cblume                int currentHeight = SkTMax(1, desc.fHeight / twoToTheMipLevel);
891790d5132620d86813380d3df251e80dd2b41a409cblume
892790d5132620d86813380d3df251e80dd2b41a409cblume                GR_GL_CALL(&interface,
893790d5132620d86813380d3df251e80dd2b41a409cblume                           TexSubImage2D(target,
894790d5132620d86813380d3df251e80dd2b41a409cblume                                         currentMipLevel,
895790d5132620d86813380d3df251e80dd2b41a409cblume                                         0, // left
896790d5132620d86813380d3df251e80dd2b41a409cblume                                         0, // top
897790d5132620d86813380d3df251e80dd2b41a409cblume                                         currentWidth,
898790d5132620d86813380d3df251e80dd2b41a409cblume                                         currentHeight,
899790d5132620d86813380d3df251e80dd2b41a409cblume                                         externalFormat, externalType,
900790d5132620d86813380d3df251e80dd2b41a409cblume                                         currentMipData));
901790d5132620d86813380d3df251e80dd2b41a409cblume            }
902e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon            return true;
903790d5132620d86813380d3df251e80dd2b41a409cblume        }
904790d5132620d86813380d3df251e80dd2b41a409cblume    } else {
905e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon        if (texels.empty()) {
906790d5132620d86813380d3df251e80dd2b41a409cblume            GL_ALLOC_CALL(&interface,
907790d5132620d86813380d3df251e80dd2b41a409cblume                          TexImage2D(target,
908e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                     0,
909790d5132620d86813380d3df251e80dd2b41a409cblume                                     internalFormat,
910e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                     baseWidth,
911e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                     baseHeight,
912790d5132620d86813380d3df251e80dd2b41a409cblume                                     0, // border
913790d5132620d86813380d3df251e80dd2b41a409cblume                                     externalFormat, externalType,
914e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                     nullptr));
915790d5132620d86813380d3df251e80dd2b41a409cblume            GrGLenum error = check_alloc_error(desc, &interface);
916790d5132620d86813380d3df251e80dd2b41a409cblume            if (error != GR_GL_NO_ERROR) {
917e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                return false;
918e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon            }
919e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon        } else {
920e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon            for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
921e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                int twoToTheMipLevel = 1 << currentMipLevel;
922e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
923e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
924e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                const void* currentMipData = texels[currentMipLevel].fPixels;
925e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                // Even if curremtMipData is nullptr, continue to call TexImage2D.
926e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                // This will allocate texture memory which we can later populate.
927e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                GL_ALLOC_CALL(&interface,
928e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                              TexImage2D(target,
929e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                         currentMipLevel,
930e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                         internalFormat,
931e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                         currentWidth,
932e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                         currentHeight,
933e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                         0, // border
934e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                         externalFormat, externalType,
935e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                                         currentMipData));
936e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                GrGLenum error = check_alloc_error(desc, &interface);
937e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                if (error != GR_GL_NO_ERROR) {
938e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                    return false;
939e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon                }
940790d5132620d86813380d3df251e80dd2b41a409cblume            }
94155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
94255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
943e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon    return true;
94455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume}
94555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
94655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume/**
94755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * Creates storage space for the texture and fills it with texels.
94855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume *
94955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param desc           The surface descriptor for the texture being created.
95055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param interface      The GL interface in use.
951790d5132620d86813380d3df251e80dd2b41a409cblume * @param caps           The capabilities of the GL device.
95255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param internalFormat The data format used for the internal storage of the texture.
95355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param texels         The texel data of the texture being created.
95455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume */
95555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblumestatic bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc,
95655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                     const GrGLInterface& interface,
957790d5132620d86813380d3df251e80dd2b41a409cblume                                                     const GrGLCaps& caps,
95855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                     GrGLenum target, GrGLenum internalFormat,
95955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                     const SkTArray<GrMipLevel>& texels,
96055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                     int baseWidth, int baseHeight) {
96155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    CLEAR_ERROR_BEFORE_ALLOC(&interface);
96255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
963790d5132620d86813380d3df251e80dd2b41a409cblume    bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig);
964790d5132620d86813380d3df251e80dd2b41a409cblume    // We can only use TexStorage if we know we will not later change the storage requirements.
965790d5132620d86813380d3df251e80dd2b41a409cblume    // This means if we may later want to add mipmaps, we cannot use TexStorage.
966790d5132620d86813380d3df251e80dd2b41a409cblume    // Right now, we cannot know if we will later add mipmaps or not.
967790d5132620d86813380d3df251e80dd2b41a409cblume    // The only time we can use TexStorage is when we already have the
968790d5132620d86813380d3df251e80dd2b41a409cblume    // mipmaps.
969790d5132620d86813380d3df251e80dd2b41a409cblume    useTexStorage &= texels.count() > 1;
97055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
971790d5132620d86813380d3df251e80dd2b41a409cblume    if (useTexStorage) {
972790d5132620d86813380d3df251e80dd2b41a409cblume        // We never resize or change formats of textures.
97355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GL_ALLOC_CALL(&interface,
974790d5132620d86813380d3df251e80dd2b41a409cblume                      TexStorage2D(target,
975790d5132620d86813380d3df251e80dd2b41a409cblume                                   texels.count(),
976790d5132620d86813380d3df251e80dd2b41a409cblume                                   internalFormat,
977790d5132620d86813380d3df251e80dd2b41a409cblume                                   baseWidth, baseHeight));
97855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GrGLenum error = check_alloc_error(desc, &interface);
97955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        if (error != GR_GL_NO_ERROR) {
98055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            return false;
981790d5132620d86813380d3df251e80dd2b41a409cblume        } else {
982790d5132620d86813380d3df251e80dd2b41a409cblume            for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
983790d5132620d86813380d3df251e80dd2b41a409cblume                const void* currentMipData = texels[currentMipLevel].fPixels;
984790d5132620d86813380d3df251e80dd2b41a409cblume                if (currentMipData == nullptr) {
985790d5132620d86813380d3df251e80dd2b41a409cblume                    continue;
986790d5132620d86813380d3df251e80dd2b41a409cblume                }
987790d5132620d86813380d3df251e80dd2b41a409cblume
988790d5132620d86813380d3df251e80dd2b41a409cblume                int twoToTheMipLevel = 1 << currentMipLevel;
989790d5132620d86813380d3df251e80dd2b41a409cblume                int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
990790d5132620d86813380d3df251e80dd2b41a409cblume                int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
991790d5132620d86813380d3df251e80dd2b41a409cblume
992790d5132620d86813380d3df251e80dd2b41a409cblume                // Make sure that the width and height that we pass to OpenGL
993790d5132620d86813380d3df251e80dd2b41a409cblume                // is a multiple of the block size.
994790d5132620d86813380d3df251e80dd2b41a409cblume                size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentWidth,
995790d5132620d86813380d3df251e80dd2b41a409cblume                                                             currentHeight);
996790d5132620d86813380d3df251e80dd2b41a409cblume                GR_GL_CALL(&interface, CompressedTexSubImage2D(target,
997790d5132620d86813380d3df251e80dd2b41a409cblume                                                               currentMipLevel,
998790d5132620d86813380d3df251e80dd2b41a409cblume                                                               0, // left
999790d5132620d86813380d3df251e80dd2b41a409cblume                                                               0, // top
1000790d5132620d86813380d3df251e80dd2b41a409cblume                                                               currentWidth,
1001790d5132620d86813380d3df251e80dd2b41a409cblume                                                               currentHeight,
1002790d5132620d86813380d3df251e80dd2b41a409cblume                                                               internalFormat,
1003790d5132620d86813380d3df251e80dd2b41a409cblume                                                               SkToInt(dataSize),
1004790d5132620d86813380d3df251e80dd2b41a409cblume                                                               currentMipData));
1005790d5132620d86813380d3df251e80dd2b41a409cblume            }
1006790d5132620d86813380d3df251e80dd2b41a409cblume        }
1007790d5132620d86813380d3df251e80dd2b41a409cblume    } else {
1008790d5132620d86813380d3df251e80dd2b41a409cblume        for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
1009790d5132620d86813380d3df251e80dd2b41a409cblume            int twoToTheMipLevel = 1 << currentMipLevel;
1010790d5132620d86813380d3df251e80dd2b41a409cblume            int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
1011790d5132620d86813380d3df251e80dd2b41a409cblume            int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
1012790d5132620d86813380d3df251e80dd2b41a409cblume
1013790d5132620d86813380d3df251e80dd2b41a409cblume            // Make sure that the width and height that we pass to OpenGL
1014790d5132620d86813380d3df251e80dd2b41a409cblume            // is a multiple of the block size.
1015790d5132620d86813380d3df251e80dd2b41a409cblume            size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth, baseHeight);
1016790d5132620d86813380d3df251e80dd2b41a409cblume
1017790d5132620d86813380d3df251e80dd2b41a409cblume            GL_ALLOC_CALL(&interface,
1018790d5132620d86813380d3df251e80dd2b41a409cblume                          CompressedTexImage2D(target,
1019790d5132620d86813380d3df251e80dd2b41a409cblume                                               currentMipLevel,
1020790d5132620d86813380d3df251e80dd2b41a409cblume                                               internalFormat,
1021790d5132620d86813380d3df251e80dd2b41a409cblume                                               currentWidth,
1022790d5132620d86813380d3df251e80dd2b41a409cblume                                               currentHeight,
1023790d5132620d86813380d3df251e80dd2b41a409cblume                                               0, // border
1024790d5132620d86813380d3df251e80dd2b41a409cblume                                               SkToInt(dataSize),
1025790d5132620d86813380d3df251e80dd2b41a409cblume                                               texels[currentMipLevel].fPixels));
1026790d5132620d86813380d3df251e80dd2b41a409cblume
1027790d5132620d86813380d3df251e80dd2b41a409cblume            GrGLenum error = check_alloc_error(desc, &interface);
1028790d5132620d86813380d3df251e80dd2b41a409cblume            if (error != GR_GL_NO_ERROR) {
1029790d5132620d86813380d3df251e80dd2b41a409cblume                return false;
1030790d5132620d86813380d3df251e80dd2b41a409cblume            }
103155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
103255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
103355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
103455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    return true;
103555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume}
103655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
103755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume/**
103855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * After a texture is created, any state which was altered during its creation
103955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * needs to be restored.
104055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume *
104155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param interface          The GL interface to use.
104255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param caps               The capabilities of the GL device.
104355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param restoreGLRowLength Should the row length unpacking be restored?
104455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume * @param glFlipY            Did GL flip the texture vertically?
104555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume */
104655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblumestatic void restore_pixelstore_state(const GrGLInterface& interface, const GrGLCaps& caps,
104755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                     bool restoreGLRowLength, bool glFlipY) {
104855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (restoreGLRowLength) {
104955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        SkASSERT(caps.unpackRowLengthSupport());
105055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
105155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
105255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (glFlipY) {
105355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
105455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
105555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume}
105655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1057861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonbool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
1058e7d7f90b59b15a291c113b449f5c6ac57f8d1aacjcgregorio                            GrGLenum target,
105917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth                            UploadType uploadType,
10606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                            int left, int top, int width, int height,
10616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                            GrPixelConfig dataConfig,
106255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                            const SkTArray<GrMipLevel>& texels) {
10636e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    // If we're uploading compressed data then we should be using uploadCompressedTexData
10646e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
10656e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org
10665b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon    SkASSERT(this->caps()->isConfigTexturable(desc.fConfig));
10675b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon
106855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // texels is const.
106955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // But we may need to flip the texture vertically to prepare it.
107055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // Rather than flip in place and alter the incoming data,
107155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // we allocate a new buffer to flip into.
107255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // This means we need to make a non-const shallow copy of texels.
107355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkTArray<GrMipLevel> texelsShallowCopy(texels);
107455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
107555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
107655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume         currentMipLevel--) {
1077e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon        SkASSERT(texelsShallowCopy[currentMipLevel].fPixels || kTransfer_UploadType == uploadType);
107855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
107955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
108055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const GrGLInterface* interface = this->glInterface();
108155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const GrGLCaps& caps = this->glCaps();
108255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1083a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    size_t bpp = GrBytesPerPixel(dataConfig);
108455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
108555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (width == 0 || height == 0) {
1086136f55b61752e01b0f140f4b7fbc8db00205a06bbsalomon@google.com        return false;
108771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com    }
10886f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
108955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
109055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int twoToTheMipLevel = 1 << currentMipLevel;
109155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int currentWidth = SkTMax(1, width / twoToTheMipLevel);
109255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int currentHeight = SkTMax(1, height / twoToTheMipLevel);
109355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
109455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        if (currentHeight > SK_MaxS32 ||
109555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            currentWidth > SK_MaxS32) {
109655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            return false;
109755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
109855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top,
109955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                               &currentWidth,
110055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                               &currentHeight,
110155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                               &texelsShallowCopy[currentMipLevel].fPixels,
110255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                               &texelsShallowCopy[currentMipLevel].fRowBytes)) {
110355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            return false;
110455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
110555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        if (currentWidth < 0 || currentHeight < 0) {
110655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            return false;
110755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
110855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
110971f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com
11105b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon    // Internal format comes from the texture desc.
111176148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum internalFormat;
11125b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon    // External format and type come from the upload data.
111376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum externalFormat;
111476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum externalType;
111576148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    if (!this->glCaps().getTexImageFormats(desc.fConfig, dataConfig, &internalFormat,
111676148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                                           &externalFormat, &externalType)) {
111776148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        return false;
111876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    }
111981a8485997162a6f2bef84b1130033b1222c722cbrianosman    // TexStorage requires a sized format, and internalFormat may or may not be
112081a8485997162a6f2bef84b1130033b1222c722cbrianosman    GrGLenum internalFormatForTexStorage = this->glCaps().configSizedInternalFormat(desc.fConfig);
112181a8485997162a6f2bef84b1130033b1222c722cbrianosman
112271f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com    /*
11235b30c6f6224f5e9d29ff7060311556ba0eee0fdcbsalomon     *  Check whether to allocate a temporary buffer for flipping y or
11246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com     *  because our srcData has extra bytes past each row. If so, we need
11256f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com     *  to trim those off here, since GL ES may not let us specify
11266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com     *  GL_UNPACK_ROW_LENGTH.
112771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com     */
11286f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    bool restoreGLRowLength = false;
11298ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com    bool swFlipY = false;
11308ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com    bool glFlipY = false;
113155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1132e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon    if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty()) {
113355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        if (caps.unpackFlipYSupport()) {
113455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            glFlipY = true;
113555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        } else {
113655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            swFlipY = true;
113771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com        }
113855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
113955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
114055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // in case we need a temporary, trimmed copy of the src pixels
114155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkAutoSMalloc<128 * 128> tempStorage;
114255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
114355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // find the combined size of all the mip levels and the relative offset of
114455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // each into the collective buffer
114555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    size_t combined_buffer_size = 0;
114655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkTArray<size_t> individual_mip_offsets(texelsShallowCopy.count());
114755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
114855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int twoToTheMipLevel = 1 << currentMipLevel;
114955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int currentWidth = SkTMax(1, width / twoToTheMipLevel);
115055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int currentHeight = SkTMax(1, height / twoToTheMipLevel);
115155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        const size_t trimmedSize = currentWidth * bpp * currentHeight;
115255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        individual_mip_offsets.push_back(combined_buffer_size);
115355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        combined_buffer_size += trimmedSize;
115455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
115555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    char* buffer = (char*)tempStorage.reset(combined_buffer_size);
115655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
115755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
115855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int twoToTheMipLevel = 1 << currentMipLevel;
115955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int currentWidth = SkTMax(1, width / twoToTheMipLevel);
116055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        int currentHeight = SkTMax(1, height / twoToTheMipLevel);
116155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        const size_t trimRowBytes = currentWidth * bpp;
116255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
116355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        /*
116455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume         *  check whether to allocate a temporary buffer for flipping y or
116555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume         *  because our srcData has extra bytes past each row. If so, we need
116655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume         *  to trim those off here, since GL ES may not let us specify
116755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume         *  GL_UNPACK_ROW_LENGTH.
116855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume         */
116955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        restoreGLRowLength = false;
117055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
117155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes;
1172154349b6fff27a19533ae528d43a5b52e4e11d3dericrk
1173154349b6fff27a19533ae528d43a5b52e4e11d3dericrk        // TODO: This optimization should be enabled with or without mips.
1174154349b6fff27a19533ae528d43a5b52e4e11d3dericrk        // For use with mips, we must set GR_GL_UNPACK_ROW_LENGTH once per
1175154349b6fff27a19533ae528d43a5b52e4e11d3dericrk        // mip level, before calling glTexImage2D.
1176154349b6fff27a19533ae528d43a5b52e4e11d3dericrk        const bool usesMips = texelsShallowCopy.count() > 1;
1177154349b6fff27a19533ae528d43a5b52e4e11d3dericrk        if (caps.unpackRowLengthSupport() && !swFlipY && !usesMips) {
1178b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com            // can't use this for flipping, only non-neg values allowed. :(
1179b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com            if (rowBytes != trimRowBytes) {
1180b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
118155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
1182b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                restoreGLRowLength = true;
118371f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com            }
118417aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth        } else if (kTransfer_UploadType != uploadType) {
1185b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com            if (trimRowBytes != rowBytes || swFlipY) {
1186b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                // copy data into our new storage, skipping the trailing bytes
118755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels;
118855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                if (swFlipY && currentHeight >= 1) {
118955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                    src += (currentHeight - 1) * rowBytes;
1190b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                }
119155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                char* dst = buffer + individual_mip_offsets[currentMipLevel];
119255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                for (int y = 0; y < currentHeight; y++) {
1193b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                    memcpy(dst, src, trimRowBytes);
1194b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                    if (swFlipY) {
1195b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                        src -= rowBytes;
1196b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                    } else {
1197b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                        src += rowBytes;
1198b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                    }
1199b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                    dst += trimRowBytes;
120071f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com                }
1201b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com                // now point data to our copied version
120255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                texelsShallowCopy[currentMipLevel].fPixels = buffer +
120355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                    individual_mip_offsets[currentMipLevel];
120455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes;
120571f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com            }
120617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth        } else {
120717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth            return false;
120871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com        }
1209e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon    }
1210e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon
1211e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon    if (!texelsShallowCopy.empty()) {
1212b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com        if (glFlipY) {
121355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
1214b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com        }
121555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT,
121655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                          config_alignment(desc.fConfig)));
121771f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com    }
121855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1219b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com    bool succeeded = true;
122055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (kNewTexture_UploadType == uploadType &&
122155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        0 == left && 0 == top &&
12227e68ab73186ab02a6030d3959e7372f983f85af5bsalomon        desc.fWidth == width && desc.fHeight == height) {
1223e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon        succeeded = allocate_and_populate_uncompressed_texture(desc, *interface, caps, target,
122481a8485997162a6f2bef84b1130033b1222c722cbrianosman                                                               internalFormat,
122581a8485997162a6f2bef84b1130033b1222c722cbrianosman                                                               internalFormatForTexStorage,
122681a8485997162a6f2bef84b1130033b1222c722cbrianosman                                                               externalFormat, externalType,
122781a8485997162a6f2bef84b1130033b1222c722cbrianosman                                                               texelsShallowCopy, width, height);
122871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com    } else {
12298ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com        if (swFlipY || glFlipY) {
12306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com            top = desc.fHeight - (top + height);
123171f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com        }
123255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count();
123355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume             currentMipLevel++) {
123455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            int twoToTheMipLevel = 1 << currentMipLevel;
123555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            int currentWidth = SkTMax(1, width / twoToTheMipLevel);
123655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            int currentHeight = SkTMax(1, height / twoToTheMipLevel);
12376f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
123855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            GL_CALL(TexSubImage2D(target,
123955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                  currentMipLevel,
124055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                  left, top,
124155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                  currentWidth,
124255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                  currentHeight,
124355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                  externalFormat, externalType,
124455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                  texelsShallowCopy[currentMipLevel].fPixels));
124555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
12468ef3fd0ca6595adb9a8172c84dc0c55c9c096e09bsalomon@google.com    }
124755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
124855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY);
124955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1250b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com    return succeeded;
125171f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com}
125271f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com
1253145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// TODO: This function is using a lot of wonky semantics like, if width == -1
1254e4b231428e8c14cbc82d20cfb12eb08fc45f8df6piotaixr// then set width = desc.fWdith ... blah. A better way to do it might be to
1255145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// create a CompressedTexData struct that takes a desc/ptr and figures out
1256145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// the proper upload semantics. Then users can construct this function how they
1257145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski// see fit if they want to go against the "standard" way to do it.
1258861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonbool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
125910528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                      GrGLenum target,
126055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                      const SkTArray<GrMipLevel>& texels,
126117aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth                                      UploadType uploadType,
1262145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski                                      int left, int top, int width, int height) {
12632555ee2e9940d00d0cc54772a934e7215d055ba2bsalomon    SkASSERT(this->caps()->isConfigTexturable(desc.fConfig));
12649c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
12659c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    // No support for software flip y, yet...
12669c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
12679c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
126855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const GrGLInterface* interface = this->glInterface();
126955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const GrGLCaps& caps = this->glCaps();
127055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1271145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    if (-1 == width) {
1272145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski        width = desc.fWidth;
1273145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    }
1274145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#ifdef SK_DEBUG
1275145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    else {
1276145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski        SkASSERT(width <= desc.fWidth);
1277145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    }
1278145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#endif
1279145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski
1280145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    if (-1 == height) {
1281145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski        height = desc.fHeight;
1282145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    }
1283145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#ifdef SK_DEBUG
1284145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    else {
1285145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski        SkASSERT(height <= desc.fHeight);
1286145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    }
1287145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski#endif
1288145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski
128976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    // We only need the internal format for compressed 2D textures.
129076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum internalFormat;
129155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (!caps.getCompressedTexImageFormats(desc.fConfig, &internalFormat)) {
129276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        return false;
129376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    }
12949c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
129517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth    if (kNewTexture_UploadType == uploadType) {
1296790d5132620d86813380d3df251e80dd2b41a409cblume        return allocate_and_populate_compressed_texture(desc, *interface, caps, target,
1297790d5132620d86813380d3df251e80dd2b41a409cblume                                                        internalFormat, texels, width, height);
1298145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    } else {
129955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
1300e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon            SkASSERT(texels[currentMipLevel].fPixels || kTransfer_UploadType == uploadType);
130155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
130255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            int twoToTheMipLevel = 1 << currentMipLevel;
130355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            int currentWidth = SkTMax(1, width / twoToTheMipLevel);
130455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            int currentHeight = SkTMax(1, height / twoToTheMipLevel);
130555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
130655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            // Make sure that the width and height that we pass to OpenGL
130755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            // is a multiple of the block size.
130855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentWidth,
130955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                         currentHeight);
131055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            GL_CALL(CompressedTexSubImage2D(target,
131155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                            currentMipLevel,
131255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                            left, top,
131355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                            currentWidth,
131455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                            currentHeight,
131555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                            internalFormat,
131655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                            SkToInt(dataSize),
131755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                            texels[currentMipLevel].fPixels));
131855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
1319145d48c4ccf1024ce0878e5110c0be7d414b7ddekrajcevski    }
13209c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
1321d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon    return true;
13229c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski}
13239c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
1324424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomonstatic bool renderbuffer_storage_msaa(const GrGLContext& ctx,
1325040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                      int sampleCount,
1326040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                      GrGLenum format,
1327040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                      int width, int height) {
13286177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com    CLEAR_ERROR_BEFORE_ALLOC(ctx.interface());
1329b1854a85095f9924947bc00e665da47b0c0bdfb9commit-bot@chromium.org    SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType());
1330b1854a85095f9924947bc00e665da47b0c0bdfb9commit-bot@chromium.org    switch (ctx.caps()->msFBOType()) {
133100731b42bcd89b98ef01b5aad3bbe51cb7018c9cBrian Salomon        case GrGLCaps::kEXT_MSFBOType:
133200731b42bcd89b98ef01b5aad3bbe51cb7018c9cBrian Salomon        case GrGLCaps::kStandard_MSFBOType:
1333dded69693dd3779f081326cde24c3954505b129dvbuzinov        case GrGLCaps::kMixedSamples_MSFBOType:
1334040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org            GL_ALLOC_CALL(ctx.interface(),
1335040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                            RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
1336040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                            sampleCount,
1337040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                            format,
1338040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                            width, height));
1339040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org            break;
1340040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org        case GrGLCaps::kES_Apple_MSFBOType:
1341040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org            GL_ALLOC_CALL(ctx.interface(),
1342040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                            RenderbufferStorageMultisampleES2APPLE(GR_GL_RENDERBUFFER,
1343040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                                    sampleCount,
1344040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                                    format,
1345040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                                    width, height));
1346040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org            break;
1347040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org        case GrGLCaps::kES_EXT_MsToTexture_MSFBOType:
1348040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org        case GrGLCaps::kES_IMG_MsToTexture_MSFBOType:
1349040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org            GL_ALLOC_CALL(ctx.interface(),
1350040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                            RenderbufferStorageMultisampleES2EXT(GR_GL_RENDERBUFFER,
1351040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                                sampleCount,
1352040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                                format,
1353040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org                                                                width, height));
1354040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org            break;
1355040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org        case GrGLCaps::kNone_MSFBOType:
135688cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Shouldn't be here if we don't support multisampled renderbuffers.");
1357040fd8f5670c8a4f73e0fe13f949681a23e6add8commit-bot@chromium.org            break;
1358c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com    }
13599251d4e9c6191aa26680911ed938dafdaebf5f61Brian Salomon    return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface()));
1360c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com}
1361c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com
1362b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdanielbool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
1363091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon                                        const GrGLTextureInfo& texInfo,
1364b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon                                        GrGLRenderTarget::IDDesc* idDesc) {
1365b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    idDesc->fMSColorRenderbufferID = 0;
1366d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    idDesc->fRTFBOID = 0;
13672e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    idDesc->fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
1368d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    idDesc->fTexFBOID = 0;
136976948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) ==
137076948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips             this->caps()->usesMixedSamples());
1371f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton    idDesc->fIsMixedSampled = desc.fSampleCnt > 0 && this->caps()->usesMixedSamples();
137281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
137381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    GrGLenum status;
137481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
1375a11e5fce33f8d6f38c3324d639ca76ddf12598babsalomon    GrGLenum colorRenderbufferFormat = 0; // suppress warning
1376ab15d618ae8c75360d414e206ae30a6845d185c4bsalomon@google.com
1377b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
1378347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com        goto FAILED;
1379347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com    }
1380347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com
1381d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    GL_CALL(GenFramebuffers(1, &idDesc->fTexFBOID));
1382d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (!idDesc->fTexFBOID) {
138381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        goto FAILED;
138481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
1385fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1386f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com    // If we are using multisampling we will create two FBOS. We render to one and then resolve to
1387f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com    // the texture bound to the other. The exception is the IMG multisample extension. With this
1388f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com    // extension the texture is multisampled when rendered to and then auto-resolves it when it is
1389f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com    // rendered from.
1390b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) {
1391d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID));
1392b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID));
1393d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        if (!idDesc->fRTFBOID ||
1394a11e5fce33f8d6f38c3324d639ca76ddf12598babsalomon            !idDesc->fMSColorRenderbufferID) {
139581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com            goto FAILED;
139681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        }
139776148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        if (!this->glCaps().getRenderbufferFormat(desc.fConfig, &colorRenderbufferFormat)) {
139876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon            return false;
139976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        }
140081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    } else {
1401d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        idDesc->fRTFBOID = idDesc->fTexFBOID;
140281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
140381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
1404d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    // below here we may bind the FBO
1405294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    fHWBoundRenderTargetUniqueID.makeInvalid();
1406d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (idDesc->fRTFBOID != idDesc->fTexFBOID) {
1407b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        SkASSERT(desc.fSampleCnt > 0);
1408b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbufferID));
1409424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon        if (!renderbuffer_storage_msaa(*fGLContext,
1410b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon                                       desc.fSampleCnt,
1411a11e5fce33f8d6f38c3324d639ca76ddf12598babsalomon                                       colorRenderbufferFormat,
1412b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon                                       desc.fWidth, desc.fHeight)) {
141381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com            goto FAILED;
141481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        }
1415d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        fStats.incRenderTargetBinds();
1416d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID));
1417d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
141810528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                        GR_GL_COLOR_ATTACHMENT0,
141910528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                        GR_GL_RENDERBUFFER,
142010528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                        idDesc->fMSColorRenderbufferID));
1421b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) ||
1422b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon            !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) {
14234bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com            GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
14244bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com            if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
14254bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com                goto FAILED;
14264bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com            }
1427424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon            fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
142881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        }
142981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
1430d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    fStats.incRenderTargetBinds();
1431d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID));
143281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
1433b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) {
1434d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
1435f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com                                                GR_GL_COLOR_ATTACHMENT0,
1436091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon                                                texInfo.fTarget,
1437091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon                                                texInfo.fID, 0, desc.fSampleCnt));
1438f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com    } else {
1439d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
1440f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com                                     GR_GL_COLOR_ATTACHMENT0,
1441091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon                                     texInfo.fTarget,
1442091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon                                     texInfo.fID, 0));
1443f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com    }
1444b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) ||
1445b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) {
1446d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
14474bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com        if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
14484bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com            goto FAILED;
14494bcb0c6e0377557d326344f4bd2bbab4e8b1bc3absalomon@google.com        }
1450424cc26add7ed491c6941d0c0c3a0e6d83190307bsalomon        fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
145181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
145281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
145381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    return true;
145481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
145581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.comFAILED:
1456b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    if (idDesc->fMSColorRenderbufferID) {
1457b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon        GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID));
145881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
1459d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (idDesc->fRTFBOID != idDesc->fTexFBOID) {
1460d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(DeleteFramebuffers(1, &idDesc->fRTFBOID));
146181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
1462d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (idDesc->fTexFBOID) {
1463d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(DeleteFramebuffers(1, &idDesc->fTexFBOID));
146481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
146581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    return false;
146681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com}
146781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
14683f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com// good to set a break-point here to know when createTexture fails
14693f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.comstatic GrTexture* return_null_texture() {
1470330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com//    SkDEBUGFAIL("null texture");
147196fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
14723f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com}
14733f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com
1474515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#if 0 && defined(SK_DEBUG)
14753f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.comstatic size_t as_size_t(int x) {
14763f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com    return x;
14773f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com}
14783f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com#endif
14793f3ffd6ad9fa4cbaef1f2a2efee2b03bf5891b3ebsalomon@google.com
14802e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunenstatic GrGLTexture::IDDesc generate_gl_texture(const GrGLInterface* interface) {
148155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GrGLTexture::IDDesc idDesc;
148255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    idDesc.fInfo.fID = 0;
148355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GR_GL_CALL(interface, GenTextures(1, &idDesc.fInfo.fID));
14842e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
148555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // When we create the texture, we only
148655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // create GL_TEXTURE_2D at the moment.
148755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // External clients can do something different.
148855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D;
148955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    return idDesc;
149055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume}
149155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
149255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblumestatic void set_initial_texture_params(const GrGLInterface* interface,
149355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                       const GrGLTextureInfo& info,
149455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                       GrGLTexture::TexParams* initialTexParams) {
149555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
149655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // drivers have a bug where an FBO won't be complete if it includes a
149755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // texture that is not mipmap complete (considering the filter in use).
149855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // we only set a subset here so invalidate first
149955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    initialTexParams->invalidate();
150055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    initialTexParams->fMinFilter = GR_GL_NEAREST;
150155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    initialTexParams->fMagFilter = GR_GL_NEAREST;
150255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    initialTexParams->fWrapS = GR_GL_CLAMP_TO_EDGE;
150355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    initialTexParams->fWrapT = GR_GL_CLAMP_TO_EDGE;
150455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GR_GL_CALL(interface, TexParameteri(info.fTarget,
150555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        GR_GL_TEXTURE_MAG_FILTER,
150655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        initialTexParams->fMagFilter));
150755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GR_GL_CALL(interface, TexParameteri(info.fTarget,
150855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        GR_GL_TEXTURE_MIN_FILTER,
150955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        initialTexParams->fMinFilter));
151055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GR_GL_CALL(interface, TexParameteri(info.fTarget,
151155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        GR_GL_TEXTURE_WRAP_S,
151255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        initialTexParams->fWrapS));
151355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GR_GL_CALL(interface, TexParameteri(info.fTarget,
151455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        GR_GL_TEXTURE_WRAP_T,
151555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                        initialTexParams->fWrapT));
151655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume}
151755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1518b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdanielGrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
15192e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen                                    SkBudgeted budgeted,
152055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                    const SkTArray<GrMipLevel>& texels) {
15218a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    // We fail if the MSAA was requested and is not available.
15228a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) {
152338406c82b913350e55fa04af8c1941cd9b4aff52tfarina        //SkDebugf("MSAA RT requested but not supported on this platform.");
15248a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        return return_null_texture();
15258a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    }
152671f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com
1527f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
1528ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1529b15b4c1ce006319acf764a25ee4a6b73283654f8bsalomon    GrGLTexture::IDDesc idDesc;
15302e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
15310a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    GrGLTexture::TexParams initialTexParams;
153255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (!this->createTextureImpl(desc, &idDesc.fInfo, renderTarget, &initialTexParams, texels)) {
1533b1d14fd63df83b40f1161473134319d13b733284bsalomon@google.com        return return_null_texture();
15346f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
1535ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1536d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips    bool wasMipMapDataProvided = false;
1537d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips    if (texels.count() > 1) {
1538d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips        wasMipMapDataProvided = true;
1539d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips    }
1540d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips
154181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    GrGLTexture* tex;
1542ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (renderTarget) {
1543ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com        // unbind the texture from the texture unit before binding it to the frame buffer
1544091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon        GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0));
15455236cf480daf82b2f36e42795abdbbc915533a59bsalomon        GrGLRenderTarget::IDDesc rtIDDesc;
1546ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
15472e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen        if (!this->createRenderTargetObjects(desc, idDesc.fInfo, &rtIDDesc)) {
1548091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon            GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
154981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com            return return_null_texture();
1550a16d6506bde44f8528e681a49c412a1e87b74482bsalomon@google.com        }
1551d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips        tex = new GrGLTextureRenderTarget(this, budgeted, desc, idDesc, rtIDDesc,
1552d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips                                          wasMipMapDataProvided);
155381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    } else {
15542e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen        tex = new GrGLTexture(this, budgeted, desc, idDesc, wasMipMapDataProvided);
155581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
15560a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
155781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com#ifdef TRACE_TEXTURE_CREATION
155838406c82b913350e55fa04af8c1941cd9b4aff52tfarina    SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
1559c4459f6a3381b033dc7871701a647820d8f6bec4brianosman             idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
156081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com#endif
156181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    return tex;
156281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com}
1563ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1564b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdanielGrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
15652e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen                                              SkBudgeted budgeted,
156655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                              const SkTArray<GrMipLevel>& texels) {
15679c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    // Make sure that we're not flipping Y.
1568b0e1be207f6b5a5346641b7b675bb9bd1993f9dfegdaniel    if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
15699c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        return return_null_texture();
15709c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    }
15719c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
15722e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface());
1573091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    if (!idDesc.fInfo.fID) {
15749c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        return return_null_texture();
15759c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    }
15769c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
15779c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    this->setScratchTextureUnit();
1578091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID));
15799c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
15809c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    GrGLTexture::TexParams initialTexParams;
158155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    set_initial_texture_params(this->glInterface(), idDesc.fInfo, &initialTexParams);
158255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
158355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (!this->uploadCompressedTexData(desc, idDesc.fInfo.fTarget, texels)) {
1584091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon        GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
15859c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        return return_null_texture();
15869c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    }
15879c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
15889c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    GrGLTexture* tex;
15892e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    tex = new GrGLTexture(this, budgeted, desc, idDesc);
15909c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
15919c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#ifdef TRACE_TEXTURE_CREATION
159238406c82b913350e55fa04af8c1941cd9b4aff52tfarina    SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n",
1593c4459f6a3381b033dc7871701a647820d8f6bec4brianosman             idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
15949c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#endif
15959c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    return tex;
15969c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski}
15979c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
159881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.comnamespace {
1599f7fa806d84abf1cba47bfa8679e875a75d76599ebsalomon@google.com
16008dc7c3a839b38b73af34cc2674a06f49eb1ce527egdanielconst GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
1601f7fa806d84abf1cba47bfa8679e875a75d76599ebsalomon@google.com
16020b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.comvoid inline get_stencil_rb_sizes(const GrGLInterface* gl,
16038dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                                 GrGLStencilAttachment::Format* format) {
16046ba0b0f9ad566e57e641c57e1f0f4876f2197010sugoi@google.com
160581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    // we shouldn't ever know one size and not the other
1606f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT((kUnknownBitCount == format->fStencilBits) ==
160781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com             (kUnknownBitCount == format->fTotalBits));
160881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    if (kUnknownBitCount == format->fStencilBits) {
16090b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
161081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com                                         GR_GL_RENDERBUFFER_STENCIL_SIZE,
161181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com                                         (GrGLint*)&format->fStencilBits);
161281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        if (format->fPacked) {
16130b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
161481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com                                             GR_GL_RENDERBUFFER_DEPTH_SIZE,
161581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com                                             (GrGLint*)&format->fTotalBits);
161681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com            format->fTotalBits += format->fStencilBits;
161781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        } else {
161881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com            format->fTotalBits = format->fStencilBits;
161981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        }
162081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
162181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com}
162281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com}
16234043ae20615c79298f190865665beeb6b86e14d0bsalomon@google.com
1624ff1d547c72b7c70af7bddfba01d4646b2389db7aegdanielint GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
1625100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon    static const int kSize = 16;
1626926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon    SkASSERT(this->caps()->isConfigRenderable(config, false));
1627304473749db1ee877addb3ddf090d2e36ede2c2absalomon    if (!this->glCaps().hasStencilFormatBeenDeterminedForConfig(config)) {
1628304473749db1ee877addb3ddf090d2e36ede2c2absalomon        // Default to unsupported, set this if we find a stencil format that works.
1629304473749db1ee877addb3ddf090d2e36ede2c2absalomon        int firstWorkingStencilFormatIndex = -1;
1630ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        // Create color texture
1631546eb5c57aebee47172f9d2a3eae6b49945dba08kkinnunen        GrGLuint colorID = 0;
1632ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(GenTextures(1, &colorID));
1633ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        this->setScratchTextureUnit();
1634ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(BindTexture(GR_GL_TEXTURE_2D, colorID));
1635ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1636ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_TEXTURE_MAG_FILTER,
1637ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_NEAREST));
1638ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1639ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_TEXTURE_MIN_FILTER,
1640ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_NEAREST));
1641ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1642ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_TEXTURE_WRAP_S,
1643ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_CLAMP_TO_EDGE));
1644ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1645ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_TEXTURE_WRAP_T,
1646ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                              GR_GL_CLAMP_TO_EDGE));
1647ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
164876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        GrGLenum internalFormat;
164976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        GrGLenum externalFormat;
165076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        GrGLenum externalType;
165176148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat,
165276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                                               &externalType)) {
165376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon            return false;
165476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        }
16554f3c253ececec7af16b8eb7c533cba31f255c953bsalomon@google.com        CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1656ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D,
1657926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon                                                      0,
165876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                                                      internalFormat,
1659100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon                                                      kSize,
1660100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon                                                      kSize,
1661ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                      0,
166276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                                                      externalFormat,
166376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                                                      externalType,
1664ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                      NULL));
1665304473749db1ee877addb3ddf090d2e36ede2c2absalomon        if (GR_GL_NO_ERROR != CHECK_ALLOC_ERROR(this->glInterface())) {
1666ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel            GL_CALL(DeleteTextures(1, &colorID));
1667304473749db1ee877addb3ddf090d2e36ede2c2absalomon            return -1;
1668fe6765293f9f16707a8f246f44c006c6e9abd33ebsalomon@google.com        }
166973165bd417d6cd4b4513df54b58e23e33f151a3frobertphillips
1670ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        // unbind the texture from the texture unit before binding it to the frame buffer
1671ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0));
1672ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
1673ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        // Create Framebuffer
1674546eb5c57aebee47172f9d2a3eae6b49945dba08kkinnunen        GrGLuint fb = 0;
1675ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(GenFramebuffers(1, &fb));
1676ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fb));
1677294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        fHWBoundRenderTargetUniqueID.makeInvalid();
1678ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
1679ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                     GR_GL_COLOR_ATTACHMENT0,
1680ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                     GR_GL_TEXTURE_2D,
1681ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                     colorID,
1682ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                     0));
1683304473749db1ee877addb3ddf090d2e36ede2c2absalomon        GrGLuint sbRBID = 0;
1684304473749db1ee877addb3ddf090d2e36ede2c2absalomon        GL_CALL(GenRenderbuffers(1, &sbRBID));
1685ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
1686ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        // look over formats till I find a compatible one
1687ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        int stencilFmtCnt = this->glCaps().stencilFormats().count();
1688304473749db1ee877addb3ddf090d2e36ede2c2absalomon        if (sbRBID) {
1689ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel            GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbRBID));
1690304473749db1ee877addb3ddf090d2e36ede2c2absalomon            for (int i = 0; i < stencilFmtCnt && sbRBID; ++i) {
1691304473749db1ee877addb3ddf090d2e36ede2c2absalomon                const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[i];
1692304473749db1ee877addb3ddf090d2e36ede2c2absalomon                CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1693304473749db1ee877addb3ddf090d2e36ede2c2absalomon                GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
1694304473749db1ee877addb3ddf090d2e36ede2c2absalomon                                                                       sFmt.fInternalFormat,
1695304473749db1ee877addb3ddf090d2e36ede2c2absalomon                                                                       kSize, kSize));
1696304473749db1ee877addb3ddf090d2e36ede2c2absalomon                if (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface())) {
1697d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel                    GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1698304473749db1ee877addb3ddf090d2e36ede2c2absalomon                                                    GR_GL_STENCIL_ATTACHMENT,
1699ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                    GR_GL_RENDERBUFFER, sbRBID));
1700304473749db1ee877addb3ddf090d2e36ede2c2absalomon                    if (sFmt.fPacked) {
1701304473749db1ee877addb3ddf090d2e36ede2c2absalomon                        GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1702304473749db1ee877addb3ddf090d2e36ede2c2absalomon                                                        GR_GL_DEPTH_ATTACHMENT,
1703304473749db1ee877addb3ddf090d2e36ede2c2absalomon                                                        GR_GL_RENDERBUFFER, sbRBID));
1704304473749db1ee877addb3ddf090d2e36ede2c2absalomon                    } else {
1705304473749db1ee877addb3ddf090d2e36ede2c2absalomon                        GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1706304473749db1ee877addb3ddf090d2e36ede2c2absalomon                                                        GR_GL_DEPTH_ATTACHMENT,
1707304473749db1ee877addb3ddf090d2e36ede2c2absalomon                                                        GR_GL_RENDERBUFFER, 0));
1708304473749db1ee877addb3ddf090d2e36ede2c2absalomon                    }
1709304473749db1ee877addb3ddf090d2e36ede2c2absalomon                    GrGLenum status;
1710304473749db1ee877addb3ddf090d2e36ede2c2absalomon                    GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1711304473749db1ee877addb3ddf090d2e36ede2c2absalomon                    if (status == GR_GL_FRAMEBUFFER_COMPLETE) {
1712304473749db1ee877addb3ddf090d2e36ede2c2absalomon                        firstWorkingStencilFormatIndex = i;
1713304473749db1ee877addb3ddf090d2e36ede2c2absalomon                        break;
1714304473749db1ee877addb3ddf090d2e36ede2c2absalomon                    }
1715ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                    GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1716ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                    GR_GL_STENCIL_ATTACHMENT,
1717ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                    GR_GL_RENDERBUFFER, 0));
1718ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                    if (sFmt.fPacked) {
1719ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                        GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1720ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                        GR_GL_DEPTH_ATTACHMENT,
1721ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                        GR_GL_RENDERBUFFER, 0));
1722ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                    }
1723ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                }
172412299ab7a1be5f4b99284ecf289d46107ef0a946bsalomon            }
1725304473749db1ee877addb3ddf090d2e36ede2c2absalomon            GL_CALL(DeleteRenderbuffers(1, &sbRBID));
1726ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
1727ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(DeleteTextures(1, &colorID));
1728ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
1729ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(DeleteFramebuffers(1, &fb));
1730304473749db1ee877addb3ddf090d2e36ede2c2absalomon        fGLContext->caps()->setStencilFormatIndexForConfig(config, firstWorkingStencilFormatIndex);
1731ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
1732304473749db1ee877addb3ddf090d2e36ede2c2absalomon    return this->glCaps().getStencilFormatIndexForConfig(config);
1733ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel}
1734ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
17359a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchenbool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
173655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                bool renderTarget, GrGLTexture::TexParams* initialTexParams,
173755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                const SkTArray<GrMipLevel>& texels) {
17389a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    info->fID = 0;
17399a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    info->fTarget = GR_GL_TEXTURE_2D;
17409a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    GL_CALL(GenTextures(1, &(info->fID)));
17419a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen
17429a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    if (!info->fID) {
17439a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen        return false;
17449a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    }
17459a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen
17469a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    this->setScratchTextureUnit();
17479a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    GL_CALL(BindTexture(info->fTarget, info->fID));
17489a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen
17499a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    if (renderTarget && this->glCaps().textureUsageSupport()) {
17509a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen        // provides a hint about how this texture will be used
17519a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen        GL_CALL(TexParameteri(info->fTarget,
17529a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen                              GR_GL_TEXTURE_USAGE,
17539a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen                              GR_GL_FRAMEBUFFER_ATTACHMENT));
17549a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    }
17559a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen
175655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (info) {
175755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        set_initial_texture_params(this->glInterface(), *info, initialTexParams);
175855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
17599a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    if (!this->uploadTexData(desc, info->fTarget, kNewTexture_UploadType, 0, 0,
17609a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen                             desc.fWidth, desc.fHeight,
176155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                             desc.fConfig, texels)) {
17629a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen        GL_CALL(DeleteTextures(1, &(info->fID)));
17639a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen        return false;
17649a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    }
17659a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen    return true;
17669a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen}
17679a1ed5d81dbfc7d5b67b568dfe12b4033a9af154erikchen
1768ec00d94199fad7723b5987b86c1abef8ddafe2d8egdanielGrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
1769ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel                                                                     int width,
1770ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel                                                                     int height) {
1771ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    SkASSERT(width >= rt->width());
1772ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    SkASSERT(height >= rt->height());
1773ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
1774ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    int samples = rt->numStencilSamples();
1775ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    GrGLStencilAttachment::IDDesc sbDesc;
1776ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
1777ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    int sIdx = this->getCompatibleStencilIndex(rt->config());
177862a627be6a7e3fdb4fe1c67de0c371a276c761f6bsalomon    if (sIdx < 0) {
1779ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel        return nullptr;
1780ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    }
1781ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel
1782ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    if (!sbDesc.fRenderbufferID) {
1783ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID));
1784ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    }
1785ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    if (!sbDesc.fRenderbufferID) {
1786ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel        return nullptr;
1787ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    }
1788ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID));
1789ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx];
1790ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1791ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    // we do this "if" so that we don't call the multisample
1792ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    // version on a GL that doesn't have an MSAA extension.
1793ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    if (samples > 0) {
1794ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        SkAssertResult(renderbuffer_storage_msaa(*fGLContext,
1795ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                 samples,
1796ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                 sFmt.fInternalFormat,
1797ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                 width, height));
1798ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    } else {
1799ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
1800ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                               sFmt.fInternalFormat,
1801ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel                                                               width, height));
1802ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel        SkASSERT(GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface()));
1803ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    }
1804ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    fStats.incStencilAttachmentCreates();
1805ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    // After sized formats we attempt an unsized format and take
1806ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    // whatever sizes GL gives us. In that case we query for the size.
1807ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    GrGLStencilAttachment::Format format = sFmt;
1808ff1d547c72b7c70af7bddfba01d4646b2389db7aegdaniel    get_stencil_rb_sizes(this->glInterface(), &format);
1809ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel    GrGLStencilAttachment* stencil = new GrGLStencilAttachment(this,
1810ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel                                                               sbDesc,
1811ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel                                                               width,
1812ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel                                                               height,
1813ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel                                                               samples,
1814ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel                                                               format);
1815ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel    return stencil;
1816ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
1817ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
181871f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
181971f341aca65f43766a81468ca81b40bbd4753ec9bsalomon@google.com
182073063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth// GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer
182173063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth// objects are implemented as client-side-arrays on tile-deferred architectures.
182273063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth#define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW
182373063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth
1824e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonGrBuffer* GrGLGpu::onCreateBuffer(size_t size, GrBufferType intendedType,
18251bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton                                  GrAccessPattern accessPattern, const void* data) {
18261bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    return GrGLBuffer::Create(this, size, intendedType, accessPattern, data);
182773063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth}
182873063dc517f424ad5660db0fbc5fe6fcc13f77f7jvanverth
1829e0d362929d6569e8737d80dead791c640390e819csmartdaltonInstancedRendering* GrGLGpu::onCreateInstancedRendering() {
1830e0d362929d6569e8737d80dead791c640390e819csmartdalton    return new GLInstancedRendering(this);
1831e0d362929d6569e8737d80dead791c640390e819csmartdalton}
1832e0d362929d6569e8737d80dead791c640390e819csmartdalton
18333e79124a69d4806f0a1a776090bff718e1b90970bsalomonvoid GrGLGpu::flushScissor(const GrScissorState& scissorState,
183477b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt                           const GrGLIRect& rtViewport,
183577b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt                           GrSurfaceOrigin rtOrigin) {
1836e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips    if (scissorState.enabled()) {
1837a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com        GrGLIRect scissor;
1838b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon        scissor.setRelativeTo(rtViewport,
1839e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips                              scissorState.rect().fLeft,
1840e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips                              scissorState.rect().fTop,
1841e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips                              scissorState.rect().width(),
1842e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips                              scissorState.rect().height(),
1843b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon                              rtOrigin);
1844a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com        // if the scissor fully contains the viewport then we fall through and
1845a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com        // disable the scissor test.
1846b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon        if (!scissor.contains(rtViewport)) {
1847a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            if (fHWScissorSettings.fRect != scissor) {
1848a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                scissor.pushToGLScissor(this->glInterface());
1849a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                fHWScissorSettings.fRect = scissor;
1850a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            }
1851a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            if (kYes_TriState != fHWScissorSettings.fEnabled) {
1852a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                GL_CALL(Enable(GR_GL_SCISSOR_TEST));
1853a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                fHWScissorSettings.fEnabled = kYes_TriState;
1854a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            }
1855a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            return;
1856a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com        }
1857730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com    }
185877b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt
185977b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt    // See fall through note above
186077b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt    this->disableScissor();
186177b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt}
186277b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt
1863bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdaltonvoid GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
1864bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton                                    const GrGLRenderTarget* rt) {
186532ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#ifndef USE_NSIGHT
1866bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    typedef GrWindowRectsState::Mode Mode;
1867bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    SkASSERT(!windowState.enabled() || rt->renderFBOID()); // Window rects can't be used on-screen.
1868bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    SkASSERT(windowState.numWindows() <= this->caps()->maxWindowRectangles());
186928341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton
187028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    if (!this->caps()->maxWindowRectangles() ||
1871bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton        fHWWindowRectsState.knownEqualTo(rt->origin(), rt->getViewport(), windowState)) {
187228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton        return;
187328341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    }
187428341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton
18757535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton    // This is purely a workaround for a spurious warning generated by gcc. Otherwise the above
18767535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton    // assert would be sufficient. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=5912
1877bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    int numWindows = SkTMin(windowState.numWindows(), int(GrWindowRectangles::kMaxWindows));
1878bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    SkASSERT(windowState.numWindows() == numWindows);
18797535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton
188028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    GrGLIRect glwindows[GrWindowRectangles::kMaxWindows];
1881bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    const SkIRect* skwindows = windowState.windows().data();
18827535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton    for (int i = 0; i < numWindows; ++i) {
18839a7677273a3f270e6137d396e972c83c036a47a7Brian Salomon        glwindows[i].setRelativeTo(rt->getViewport(), skwindows[i], rt->origin());
188428341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    }
188528341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton
1886bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE;
18877535f419e235e224559ee2b4b62ee6bfddc01556csmartdalton    GL_CALL(WindowRectangles(glmode, numWindows, glwindows->asInts()));
188828341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton
1889bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    fHWWindowRectsState.set(rt->origin(), rt->getViewport(), windowState);
189032ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#endif
189128341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton}
189228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton
189328341fad8438b294ed7311edbc68d8cb34a990abcsmartdaltonvoid GrGLGpu::disableWindowRectangles() {
189432ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#ifndef USE_NSIGHT
1895bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    if (!this->caps()->maxWindowRectangles() || fHWWindowRectsState.knownDisabled()) {
189628341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton        return;
189728341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    }
189828341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    GL_CALL(WindowRectangles(GR_GL_EXCLUSIVE, 0, nullptr));
1899bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    fHWWindowRectsState.setDisabled();
190032ac83ebdc4ac967aae95a48a62c991d459dab73Jim Van Verth#endif
190128341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton}
190228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton
190328ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholasvoid GrGLGpu::flushMinSampleShading(float minSampleShading) {
190428ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas    if (fHWMinSampleShading != minSampleShading) {
190528ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas        if (minSampleShading > 0.0) {
190628ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas            GL_CALL(Enable(GR_GL_SAMPLE_SHADING));
190728ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas            GL_CALL(MinSampleShading(minSampleShading));
190828ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas        }
190928ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas        else {
191028ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas            GL_CALL(Disable(GR_GL_SAMPLE_SHADING));
191128ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas        }
191228ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas        fHWMinSampleShading = minSampleShading;
191328ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas    }
191428ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas}
191528ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas
19162eda5b3a65f54105ae3776160373eed5500c515fbsalomonbool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc,
19172eda5b3a65f54105ae3776160373eed5500c515fbsalomon                           bool willDrawPoints) {
1918144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc, willDrawPoints));
191933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (!program) {
192033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GrCapsDebugf(this->caps(), "Failed to create program!\n");
192133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return false;
192233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
192333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
192433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    program->generateMipmaps(primProc, pipeline);
192533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
1926080e673b10ac607305f140ddb245e140ccde40c6egdaniel    GrXferProcessor::BlendInfo blendInfo;
19270e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel    pipeline.getXferProcessor().getBlendInfo(&blendInfo);
1928080e673b10ac607305f140ddb245e140ccde40c6egdaniel
1929080e673b10ac607305f140ddb245e140ccde40c6egdaniel    this->flushColorWrite(blendInfo.fWriteColor);
19308dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    this->flushDrawFace(pipeline.getDrawFace());
193128ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas    this->flushMinSampleShading(primProc.getSampleShading());
1932bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
19336df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLuint programID = program->programID();
19341f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon    if (fHWProgramID != programID) {
19351f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon        GL_CALL(UseProgram(programID));
19361f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon        fHWProgramID = programID;
19371f78c0a2ddacee6e1957b716eb8bb3961b278de7bsalomon    }
1938bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1939d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (blendInfo.fWriteColor) {
19407f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        // Swizzle the blend to match what the shader will output.
19411edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        const GrSwizzle& swizzle = this->caps()->shaderCaps()->configOutputSwizzle(
19420e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel            pipeline.getRenderTarget()->config());
19437f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        this->flushBlend(blendInfo, swizzle);
1944d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    }
1945bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
194674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    program->setData(primProc, pipeline);
1947bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1948898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
1949c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton    GrStencilSettings stencil;
1950c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton    if (pipeline.isStencilEnabled()) {
1951c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton        // TODO: attach stencil and create settings during render target flush.
1952c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton        SkASSERT(glRT->renderTargetPriv().getStencilAttachment());
1953c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton        stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
1954c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton                      glRT->renderTargetPriv().numStencilBits());
1955c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton    }
1956c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton    this->flushStencil(stencil);
19578dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
1958bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT);
1959dabc91bc0f42a9484b6025ddc68fa958455fb53ccsmartdalton    this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled());
1960bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1961bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon    // This must come after textures are flushed because a texture may need
1962d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    // to be msaa-resolved (which will modify bound FBO state).
196364d094d7756534a9b9b0997aab225d9ceba098b6brianosman    this->flushRenderTarget(glRT, nullptr, pipeline.getDisableOutputConversionToSRGB());
1964bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1965bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon    return true;
1966bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon}
1967bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1968873ad0e0b4d67bdc7bad025018f597450e7004c6joshualittvoid GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
19690e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel                            const GrNonInstancedMesh& mesh,
1970bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon                            size_t* indexOffsetInBytes) {
1971485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton    const GrBuffer* vbuf = mesh.vertexBuffer();
1972bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon    SkASSERT(vbuf);
1973bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon    SkASSERT(!vbuf->isMapped());
1974bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1975e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GrGLAttribArrayState* attribState;
19760e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel    if (mesh.isIndexed()) {
1977bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        SkASSERT(indexOffsetInBytes);
1978bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1979bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        *indexOffsetInBytes = 0;
1980485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton        const GrBuffer* ibuf = mesh.indexBuffer();
1981bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        SkASSERT(ibuf);
1982bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        SkASSERT(!ibuf->isMapped());
1983bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        *indexOffsetInBytes += ibuf->baseOffset();
1984e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        attribState = fHWVertexArrayState.bindInternalVertexArray(this, ibuf);
1985e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    } else {
1986e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        attribState = fHWVertexArrayState.bindInternalVertexArray(this);
1987bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon    }
1988bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1989873ad0e0b4d67bdc7bad025018f597450e7004c6joshualitt    int vaCount = primProc.numAttribs();
199071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    if (vaCount > 0) {
1991bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1992873ad0e0b4d67bdc7bad025018f597450e7004c6joshualitt        GrGLsizei stride = static_cast<GrGLsizei>(primProc.getVertexStride());
1993bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
19940e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        size_t vertexOffsetInBytes = stride * mesh.startVertex();
1995bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1996bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        vertexOffsetInBytes += vbuf->baseOffset();
1997bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
1998bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        uint32_t usedAttribArraysMask = 0;
1999bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        size_t offset = 0;
2000bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
2001bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) {
2002873ad0e0b4d67bdc7bad025018f597450e7004c6joshualitt            const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(attribIndex);
2003bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon            usedAttribArraysMask |= (1 << attribIndex);
200471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt            GrVertexAttribType attribType = attrib.fType;
2005bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon            attribState->set(this,
2006bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon                             attribIndex,
2007e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                             vbuf,
2008793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton                             attribType,
2009bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon                             stride,
2010bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon                             reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + offset));
201171c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt            offset += attrib.fOffset;
2012bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        }
2013bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon        attribState->disableUnusedArrays(this, usedAttribArraysMask);
2014bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon    }
2015bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon}
2016bc3d0de755c4164563d136fc6b28fc186d275db7bsalomon
2017485a12003ab48b54965d6f7172f3183358919d8ecsmartdaltonGrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrBuffer* buffer) {
201893316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt    this->handleDirtyContext();
2019e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
2020e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    // Index buffer state is tied to the vertex array.
2021e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (kIndex_GrBufferType == type) {
2022e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        this->bindVertexArray(0);
202393316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt    }
202493316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt
2025e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    SkASSERT(type >= 0 && type <= kLast_GrBufferType);
2026e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    auto& bufferState = fHWBufferState[type];
2027e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
20288abb370aca280516f4861c6c942ec453aad018farobertphillips    if (buffer->uniqueID() != bufferState.fBoundBufferUniqueID) {
2029485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton        if (buffer->isCPUBacked()) {
2030485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton            if (!bufferState.fBufferZeroKnownBound) {
2031485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton                GL_CALL(BindBuffer(bufferState.fGLTarget, 0));
2032485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton            }
2033485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton        } else {
2034485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton            const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(buffer);
2035485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton            GL_CALL(BindBuffer(bufferState.fGLTarget, glBuffer->bufferID()));
2036e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        }
2037485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton        bufferState.fBufferZeroKnownBound = buffer->isCPUBacked();
20388abb370aca280516f4861c6c942ec453aad018farobertphillips        bufferState.fBoundBufferUniqueID = buffer->uniqueID();
203993316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt    }
2040e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
2041e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    return bufferState.fGLTarget;
204293316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt}
204393316b92e565072e2b6fe4147802a9ffaf92eb77joshualitt
204474b8d323323c8533e3e5cc7719e0bd127aacd829cdaltonvoid GrGLGpu::notifyBufferReleased(const GrGLBuffer* buffer) {
204574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    if (buffer->hasAttachedToTexture()) {
204674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        // Detach this buffer from any textures to ensure the underlying memory is freed.
2047294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        GrGpuResource::UniqueID uniqueID = buffer->uniqueID();
204874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        for (int i = fHWMaxUsedBufferTextureUnit; i >= 0; --i) {
204974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            auto& buffTex = fHWBufferTextures[i];
205074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            if (uniqueID != buffTex.fAttachedBufferUniqueID) {
205174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                continue;
205274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            }
205374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            if (i == fHWMaxUsedBufferTextureUnit) {
205474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                --fHWMaxUsedBufferTextureUnit;
205574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            }
205674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
205774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            this->setTextureUnit(i);
205874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            if (!buffTex.fKnownBound) {
205974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                SkASSERT(buffTex.fTextureID);
206074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID));
206174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                buffTex.fKnownBound = true;
206274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            }
206374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER,
206474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                              this->glCaps().configSizedInternalFormat(buffTex.fTexelConfig), 0));
206574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        }
206674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    }
206774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton}
206874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
2069861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::disableScissor() {
2070a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com    if (kNo_TriState != fHWScissorSettings.fEnabled) {
2071730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com        GL_CALL(Disable(GR_GL_SCISSOR_TEST));
2072a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com        fHWScissorSettings.fEnabled = kNo_TriState;
2073a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com        return;
2074ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
2075ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2076ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
207729df76096fd30941086324902a82656df2d8becdcsmartdaltonvoid GrGLGpu::clear(const GrFixedClip& clip, GrColor color, GrRenderTarget* target) {
20789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    this->handleDirtyContext();
20799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
20800ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com    // parent class should never let us get here with no RT
208149f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(target);
2082b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
20830ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com
208429df76096fd30941086324902a82656df2d8becdcsmartdalton    this->flushRenderTarget(glRT, clip.scissorEnabled() ? &clip.scissorRect() : nullptr);
208529df76096fd30941086324902a82656df2d8becdcsmartdalton    this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
2086bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    this->flushWindowRectangles(clip.windowRectsState(), glRT);
208774b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com
208874b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    GrGLfloat r, g, b, a;
208974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    static const GrGLfloat scale255 = 1.f / 255.f;
209074b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    a = GrColorUnpackA(color) * scale255;
209174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    GrGLfloat scaleRGB = scale255;
209274b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    r = GrColorUnpackR(color) * scaleRGB;
209374b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    g = GrColorUnpackG(color) * scaleRGB;
209474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    b = GrColorUnpackB(color) * scaleRGB;
209574b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com
209674b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
2097978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com    fHWWriteToColor = kYes_TriState;
209874b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com    GL_CALL(ClearColor(r, g, b, a));
20990b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
2100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2102861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::clearStencil(GrRenderTarget* target) {
210396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == target) {
21047d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com        return;
21057d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    }
2106b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
2107d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
21088295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
210977b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt    this->disableScissor();
211028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    this->disableWindowRectangles();
2111730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com
21120b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    GL_CALL(StencilMask(0xffffffff));
21130b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    GL_CALL(ClearStencil(0));
21140b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
2115457b8a3b49d5cf946674bbaa959a86bd137bf582bsalomon@google.com    fHWStencilSettings.invalidate();
2116ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2117ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
211829df76096fd30941086324902a82656df2d8becdcsmartdaltonvoid GrGLGpu::clearStencilClip(const GrFixedClip& clip,
211929df76096fd30941086324902a82656df2d8becdcsmartdalton                               bool insideStencilMask,
212029df76096fd30941086324902a82656df2d8becdcsmartdalton                               GrRenderTarget* target) {
212149f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(target);
21229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    this->handleDirtyContext();
212381c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
21248dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel    GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
212581c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    // this should only be called internally when we know we have a
212681c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    // stencil buffer.
21276bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    SkASSERT(sb);
21286bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    GrGLint stencilBitCount =  sb->bits();
2129ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com#if 0
2130f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(stencilBitCount > 0);
21310f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
21325aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com#else
21335aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com    // we could just clear the clip bit but when we go through
213481c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    // ANGLE a partial stencil mask will cause clears to be
2135f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    // turned into draws. Our contract on GrOpList says that
21365aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com    // changing the clip between stencil passes may or may not
21375aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com    // zero the client's clip bits. So we just clear the whole thing.
21380f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    static const GrGLint clipStencilMask  = ~0;
21395aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com#endif
2140ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com    GrGLint value;
214129df76096fd30941086324902a82656df2d8becdcsmartdalton    if (insideStencilMask) {
2142ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com        value = (1 << (stencilBitCount - 1));
2143ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com    } else {
2144ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com        value = 0;
2145ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com    }
2146b0bd4f64a6827dda6f4ec48e4746b0f0b72a975fbsalomon    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
2147d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
2148a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com
214929df76096fd30941086324902a82656df2d8becdcsmartdalton    this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
2150bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    this->flushWindowRectangles(clip.windowRectsState(), glRT);
2151a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com
2152cf6285b89b8820641ffb6871d4b3275bfe783f51caryclark@google.com    GL_CALL(StencilMask((uint32_t) clipStencilMask));
2153ab3dee5c8a7b782f2cf2464316867f2efb2a5cf3bsalomon@google.com    GL_CALL(ClearStencil(value));
21540b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
2155457b8a3b49d5cf946674bbaa959a86bd137bf582bsalomon@google.com    fHWStencilSettings.invalidate();
2156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
215871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomonstatic bool read_pixels_pays_for_y_flip(GrSurfaceOrigin origin, const GrGLCaps& caps,
2159398260262f8508687614ec496a23b8152bcdc967bsalomon                                        int width, int height,  GrPixelConfig config,
2160398260262f8508687614ec496a23b8152bcdc967bsalomon                                        size_t rowBytes) {
216171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    // If the surface is already TopLeft, we don't need to flip.
216271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (kTopLeft_GrSurfaceOrigin == origin) {
21633cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org        return false;
21643cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    }
21653cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org
2166494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon    // If the read is really small or smaller than the min texture size, don't force a draw.
2167100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon    static const int kMinSize = 32;
2168100b8f8c079510a6b7572f9ed8058c1d4a2bfebabsalomon    if (width < kMinSize || height < kMinSize) {
2169494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon        return false;
2170494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon    }
2171494aa593c59d3f426036f87ef1fab1ea158c469fbsalomon
217256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com    // if GL can do the flip then we'll never pay for it.
2173398260262f8508687614ec496a23b8152bcdc967bsalomon    if (caps.packFlipYSupport()) {
217456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        return false;
217556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com    }
217656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com
217756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com    // If we have to do memcpy to handle non-trim rowBytes then we
21787107fa789a5999e3f8f7cf7c9c4208c2c443d2afbsalomon@google.com    // get the flip for free. Otherwise it costs.
2179398260262f8508687614ec496a23b8152bcdc967bsalomon    // Note that we're assuming that 0 rowBytes has already been handled and that the width has been
2180398260262f8508687614ec496a23b8152bcdc967bsalomon    // clipped.
2181398260262f8508687614ec496a23b8152bcdc967bsalomon    return caps.packRowLengthSupport() || GrBytesPerPixel(config) * width == rowBytes;
2182398260262f8508687614ec496a23b8152bcdc967bsalomon}
2183398260262f8508687614ec496a23b8152bcdc967bsalomon
21841aa202935ff698f1f35c5435455073fd9f1d08debsalomonbool GrGLGpu::readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig) {
2185625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon#ifdef SK_BUILD_FOR_MAC
2186625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon    // Chromium may ask us to read back from locked IOSurfaces. Calling the command buffer's
2187625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon    // glGetIntegerv() with GL_IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE causes the command buffer
2188625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon    // to make a call to check the framebuffer status which can hang the driver. So in Mac Chromium
2189625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon    // we always use a temporary surface to test for read pixels support.
2190625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon    // https://www.crbug.com/662802
2191625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon    if (this->glContext().driver() == kChromium_GrGLDriver) {
2192625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon        return this->readPixelsSupported(target->config(), readConfig);
2193625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon    }
2194625cd9e0c9379b45c7f3100677eefcf5e241d032Brian Salomon#endif
21951aa202935ff698f1f35c5435455073fd9f1d08debsalomon    auto bindRenderTarget = [this, target]() -> bool {
21961aa202935ff698f1f35c5435455073fd9f1d08debsalomon        this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target), &SkIRect::EmptyIRect());
21971aa202935ff698f1f35c5435455073fd9f1d08debsalomon        return true;
21981aa202935ff698f1f35c5435455073fd9f1d08debsalomon    };
21992c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon    auto unbindRenderTarget = []{};
22001aa202935ff698f1f35c5435455073fd9f1d08debsalomon    auto getIntegerv = [this](GrGLenum query, GrGLint* value) {
22011aa202935ff698f1f35c5435455073fd9f1d08debsalomon        GR_GL_GetIntegerv(this->glInterface(), query, value);
22021aa202935ff698f1f35c5435455073fd9f1d08debsalomon    };
22031aa202935ff698f1f35c5435455073fd9f1d08debsalomon    GrPixelConfig rtConfig = target->config();
22042c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon    return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget,
22052c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon                                              unbindRenderTarget);
22061aa202935ff698f1f35c5435455073fd9f1d08debsalomon}
22071aa202935ff698f1f35c5435455073fd9f1d08debsalomon
22081aa202935ff698f1f35c5435455073fd9f1d08debsalomonbool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConfig) {
22092c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon    sk_sp<GrTexture> temp;
22102c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon    auto bindRenderTarget = [this, rtConfig, &temp]() -> bool {
22111aa202935ff698f1f35c5435455073fd9f1d08debsalomon        GrTextureDesc desc;
22121aa202935ff698f1f35c5435455073fd9f1d08debsalomon        desc.fConfig = rtConfig;
22131aa202935ff698f1f35c5435455073fd9f1d08debsalomon        desc.fWidth = desc.fHeight = 16;
22142c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon        if (this->glCaps().isConfigRenderable(rtConfig, false)) {
22152c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            desc.fFlags = kRenderTarget_GrSurfaceFlag;
22162c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            temp.reset(this->createTexture(desc, SkBudgeted::kNo));
22172c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            if (!temp) {
22182c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon                return false;
22192c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            }
22202c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(temp->asRenderTarget());
22212c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            this->flushRenderTarget(glrt, &SkIRect::EmptyIRect());
22222c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            return true;
22232c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon        } else if (this->glCaps().canConfigBeFBOColorAttachment(rtConfig)) {
22242c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            temp.reset(this->createTexture(desc, SkBudgeted::kNo));
22252c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            if (!temp) {
22262c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon                return false;
22272c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            }
22282c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            GrGLIRect vp;
22292c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            this->bindSurfaceFBOForPixelOps(temp.get(), GR_GL_FRAMEBUFFER, &vp, kDst_TempFBOTarget);
2230294870ff119b89fc902773643b054f14e5d1f554Robert Phillips            fHWBoundRenderTargetUniqueID.makeInvalid();
22312c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon            return true;
22321aa202935ff698f1f35c5435455073fd9f1d08debsalomon        }
22332c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon        return false;
22342c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon    };
22352c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon    auto unbindRenderTarget = [this, &temp]() {
22362c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon        this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, temp.get());
22371aa202935ff698f1f35c5435455073fd9f1d08debsalomon    };
22381aa202935ff698f1f35c5435455073fd9f1d08debsalomon    auto getIntegerv = [this](GrGLenum query, GrGLint* value) {
22391aa202935ff698f1f35c5435455073fd9f1d08debsalomon        GR_GL_GetIntegerv(this->glInterface(), query, value);
22401aa202935ff698f1f35c5435455073fd9f1d08debsalomon    };
22412c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon    return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget,
22422c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5bsalomon                                              unbindRenderTarget);
22431aa202935ff698f1f35c5435455073fd9f1d08debsalomon}
22441aa202935ff698f1f35c5435455073fd9f1d08debsalomon
22451aa202935ff698f1f35c5435455073fd9f1d08debsalomonbool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig) {
22461aa202935ff698f1f35c5435455073fd9f1d08debsalomon    if (GrRenderTarget* rt = surfaceForConfig->asRenderTarget()) {
22471aa202935ff698f1f35c5435455073fd9f1d08debsalomon        return this->readPixelsSupported(rt, readConfig);
22481aa202935ff698f1f35c5435455073fd9f1d08debsalomon    } else {
22491aa202935ff698f1f35c5435455073fd9f1d08debsalomon        GrPixelConfig config = surfaceForConfig->config();
22501aa202935ff698f1f35c5435455073fd9f1d08debsalomon        return this->readPixelsSupported(config, readConfig);
22511aa202935ff698f1f35c5435455073fd9f1d08debsalomon    }
22521aa202935ff698f1f35c5435455073fd9f1d08debsalomon}
22531aa202935ff698f1f35c5435455073fd9f1d08debsalomon
2254e9573317d35d08254412eb407211f3607f8f74fbbsalomonstatic bool requires_srgb_conversion(GrPixelConfig a, GrPixelConfig b) {
2255e9573317d35d08254412eb407211f3607f8f74fbbsalomon    if (GrPixelConfigIsSRGB(a)) {
2256e9573317d35d08254412eb407211f3607f8f74fbbsalomon        return !GrPixelConfigIsSRGB(b) && !GrPixelConfigIsAlphaOnly(b);
2257e9573317d35d08254412eb407211f3607f8f74fbbsalomon    } else if (GrPixelConfigIsSRGB(b)) {
2258e9573317d35d08254412eb407211f3607f8f74fbbsalomon        return !GrPixelConfigIsSRGB(a) && !GrPixelConfigIsAlphaOnly(a);
2259e9573317d35d08254412eb407211f3607f8f74fbbsalomon    }
2260e9573317d35d08254412eb407211f3607f8f74fbbsalomon    return false;
2261e9573317d35d08254412eb407211f3607f8f74fbbsalomon}
2262e9573317d35d08254412eb407211f3607f8f74fbbsalomon
2263f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomonbool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
2264f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                                  GrPixelConfig readConfig, DrawPreference* drawPreference,
2265f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                                  ReadPixelTempDrawInfo* tempDrawInfo) {
2266e9573317d35d08254412eb407211f3607f8f74fbbsalomon    GrPixelConfig srcConfig = srcSurface->config();
2267398260262f8508687614ec496a23b8152bcdc967bsalomon
2268e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // These settings we will always want if a temp draw is performed.
2269398260262f8508687614ec496a23b8152bcdc967bsalomon    tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
2270398260262f8508687614ec496a23b8152bcdc967bsalomon    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
2271398260262f8508687614ec496a23b8152bcdc967bsalomon    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
2272398260262f8508687614ec496a23b8152bcdc967bsalomon    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
2273398260262f8508687614ec496a23b8152bcdc967bsalomon    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
2274b117ff194ff888ef9107a4797aad053b0d76be30bsalomon    tempDrawInfo->fTempSurfaceFit = this->glCaps().partialFBOReadIsSlow() ? SkBackingFit::kExact
2275b117ff194ff888ef9107a4797aad053b0d76be30bsalomon                                                                          : SkBackingFit::kApprox;
2276e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // For now assume no swizzling, we may change that below.
2277e9573317d35d08254412eb407211f3607f8f74fbbsalomon    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
2278e9573317d35d08254412eb407211f3607f8f74fbbsalomon
2279e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read
2280e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // from will be srcConfig and we will read readConfig pixels from it.
2281e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // Not that if we require a draw and return a non-renderable format for the temp surface the
2282e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // base class will fail for us.
2283e9573317d35d08254412eb407211f3607f8f74fbbsalomon    tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
2284e9573317d35d08254412eb407211f3607f8f74fbbsalomon    tempDrawInfo->fReadConfig = readConfig;
2285e9573317d35d08254412eb407211f3607f8f74fbbsalomon
2286e9573317d35d08254412eb407211f3607f8f74fbbsalomon    if (requires_srgb_conversion(srcConfig, readConfig)) {
2287e9573317d35d08254412eb407211f3607f8f74fbbsalomon        if (!this->readPixelsSupported(readConfig, readConfig)) {
2288e9573317d35d08254412eb407211f3607f8f74fbbsalomon            return false;
2289e9573317d35d08254412eb407211f3607f8f74fbbsalomon        }
2290e9573317d35d08254412eb407211f3607f8f74fbbsalomon        // Draw to do srgb to linear conversion or vice versa.
2291e9573317d35d08254412eb407211f3607f8f74fbbsalomon        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2292e9573317d35d08254412eb407211f3607f8f74fbbsalomon        tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
2293e9573317d35d08254412eb407211f3607f8f74fbbsalomon        tempDrawInfo->fReadConfig = readConfig;
2294e9573317d35d08254412eb407211f3607f8f74fbbsalomon        return true;
2295e9573317d35d08254412eb407211f3607f8f74fbbsalomon    }
2296e9573317d35d08254412eb407211f3607f8f74fbbsalomon
22971aa202935ff698f1f35c5435455073fd9f1d08debsalomon    if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig &&
22981aa202935ff698f1f35c5435455073fd9f1d08debsalomon        this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelConfig)) {
2299398260262f8508687614ec496a23b8152bcdc967bsalomon        tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig;
23006c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon        tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
23016c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon        tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig;
2302b411b3b87dcdfc124f7eec5581d510a5282a8563bsalomon        ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2303b4ecabd5a2c359f66a20207ffb02a77e624560c4ericrk    } else if (this->glCaps().rgbaToBgraReadbackConversionsAreSlow() &&
2304398260262f8508687614ec496a23b8152bcdc967bsalomon               GrBytesPerPixel(readConfig) == 4 &&
23051aa202935ff698f1f35c5435455073fd9f1d08debsalomon               GrPixelConfigSwapRAndB(readConfig) == srcConfig &&
23061aa202935ff698f1f35c5435455073fd9f1d08debsalomon               this->readPixelsSupported(srcSurface, srcConfig)) {
23076c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon        // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa.
2308398260262f8508687614ec496a23b8152bcdc967bsalomon        // Better to do a draw with a R/B swap and then read as the original config.
2309398260262f8508687614ec496a23b8152bcdc967bsalomon        tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
23106c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon        tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
23116c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon        tempDrawInfo->fReadConfig = srcConfig;
2312f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
23131aa202935ff698f1f35c5435455073fd9f1d08debsalomon    } else if (!this->readPixelsSupported(srcSurface, readConfig)) {
23141aa202935ff698f1f35c5435455073fd9f1d08debsalomon        if (readConfig == kBGRA_8888_GrPixelConfig &&
231571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig) &&
23161aa202935ff698f1f35c5435455073fd9f1d08debsalomon            this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPixelConfig)) {
2317e9573317d35d08254412eb407211f3607f8f74fbbsalomon            // We're trying to read BGRA but it's not supported. If RGBA is renderable and
2318e9573317d35d08254412eb407211f3607f8f74fbbsalomon            // we can read it back, then do a swizzling draw to a RGBA and read it back (which
2319e9573317d35d08254412eb407211f3607f8f74fbbsalomon            // will effectively be BGRA).
23201aa202935ff698f1f35c5435455073fd9f1d08debsalomon            tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
23211aa202935ff698f1f35c5435455073fd9f1d08debsalomon            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
23221aa202935ff698f1f35c5435455073fd9f1d08debsalomon            tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig;
23231aa202935ff698f1f35c5435455073fd9f1d08debsalomon            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2324a6359365887048ef055196de75591311d7a015f0brianosman        } else if (readConfig == kSBGRA_8888_GrPixelConfig &&
232571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) &&
2326a6359365887048ef055196de75591311d7a015f0brianosman            this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, kSRGBA_8888_GrPixelConfig)) {
2327a6359365887048ef055196de75591311d7a015f0brianosman            // We're trying to read sBGRA but it's not supported. If sRGBA is renderable and
2328a6359365887048ef055196de75591311d7a015f0brianosman            // we can read it back, then do a swizzling draw to a sRGBA and read it back (which
2329a6359365887048ef055196de75591311d7a015f0brianosman            // will effectively be sBGRA).
2330a6359365887048ef055196de75591311d7a015f0brianosman            tempDrawInfo->fTempSurfaceDesc.fConfig = kSRGBA_8888_GrPixelConfig;
2331a6359365887048ef055196de75591311d7a015f0brianosman            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2332a6359365887048ef055196de75591311d7a015f0brianosman            tempDrawInfo->fReadConfig = kSRGBA_8888_GrPixelConfig;
2333a6359365887048ef055196de75591311d7a015f0brianosman            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2334e9573317d35d08254412eb407211f3607f8f74fbbsalomon        } else if (readConfig == kAlpha_8_GrPixelConfig) {
2335e9573317d35d08254412eb407211f3607f8f74fbbsalomon            // onReadPixels implements a fallback for cases where we are want to read kAlpha_8,
2336e9573317d35d08254412eb407211f3607f8f74fbbsalomon            // it's unsupported, but 32bit RGBA reads are supported.
2337e9573317d35d08254412eb407211f3607f8f74fbbsalomon            // Don't attempt to do any srgb conversions since we only care about alpha.
2338e9573317d35d08254412eb407211f3607f8f74fbbsalomon            GrPixelConfig cpuTempConfig = kRGBA_8888_GrPixelConfig;
2339e9573317d35d08254412eb407211f3607f8f74fbbsalomon            if (GrPixelConfigIsSRGB(srcSurface->config())) {
2340e9573317d35d08254412eb407211f3607f8f74fbbsalomon                cpuTempConfig = kSRGBA_8888_GrPixelConfig;
2341e9573317d35d08254412eb407211f3607f8f74fbbsalomon            }
2342e9573317d35d08254412eb407211f3607f8f74fbbsalomon            if (!this->readPixelsSupported(srcSurface, cpuTempConfig)) {
2343e9573317d35d08254412eb407211f3607f8f74fbbsalomon                // If we can't read RGBA from the src try to draw to a kRGBA_8888 (or kSRGBA_8888)
2344e9573317d35d08254412eb407211f3607f8f74fbbsalomon                // first and then onReadPixels will read that to a 32bit temporary buffer.
234571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                if (this->glCaps().canConfigBeFBOColorAttachment(cpuTempConfig)) {
2346e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2347e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    tempDrawInfo->fTempSurfaceDesc.fConfig = cpuTempConfig;
2348e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    tempDrawInfo->fReadConfig = kAlpha_8_GrPixelConfig;
2349e9573317d35d08254412eb407211f3607f8f74fbbsalomon                } else {
2350e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    return false;
2351e9573317d35d08254412eb407211f3607f8f74fbbsalomon                }
2352e9573317d35d08254412eb407211f3607f8f74fbbsalomon            } else {
2353e9573317d35d08254412eb407211f3607f8f74fbbsalomon                SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
2354e9573317d35d08254412eb407211f3607f8f74fbbsalomon                SkASSERT(tempDrawInfo->fReadConfig == kAlpha_8_GrPixelConfig);
2355e9573317d35d08254412eb407211f3607f8f74fbbsalomon            }
235671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        } else if (this->glCaps().canConfigBeFBOColorAttachment(readConfig) &&
2357e6d665e24feabf6c633452885910efd17e5f025ebsalomon                   this->readPixelsSupported(readConfig, readConfig)) {
2358e6d665e24feabf6c633452885910efd17e5f025ebsalomon            // Do a draw to convert from the src config to the read config.
2359e6d665e24feabf6c633452885910efd17e5f025ebsalomon            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2360e6d665e24feabf6c633452885910efd17e5f025ebsalomon            tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
2361e6d665e24feabf6c633452885910efd17e5f025ebsalomon            tempDrawInfo->fReadConfig = readConfig;
23621aa202935ff698f1f35c5435455073fd9f1d08debsalomon        } else {
23631aa202935ff698f1f35c5435455073fd9f1d08debsalomon            return false;
23641aa202935ff698f1f35c5435455073fd9f1d08debsalomon        }
2365398260262f8508687614ec496a23b8152bcdc967bsalomon    }
2366398260262f8508687614ec496a23b8152bcdc967bsalomon
236771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if ((srcSurface->asRenderTarget() || this->glCaps().canConfigBeFBOColorAttachment(srcConfig)) &&
236871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        read_pixels_pays_for_y_flip(srcSurface->origin(), this->glCaps(), width, height, readConfig,
236971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                                    rowBytes)) {
2370f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2371398260262f8508687614ec496a23b8152bcdc967bsalomon    }
2372398260262f8508687614ec496a23b8152bcdc967bsalomon
2373398260262f8508687614ec496a23b8152bcdc967bsalomon    return true;
2374c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com}
2375c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
23766cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomonbool GrGLGpu::onReadPixels(GrSurface* surface,
2377c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                           int left, int top,
2378c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                           int width, int height,
2379c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                           GrPixelConfig config,
2380c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                           void* buffer,
23813cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org                           size_t rowBytes) {
23826cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    SkASSERT(surface);
2383398260262f8508687614ec496a23b8152bcdc967bsalomon
2384e9573317d35d08254412eb407211f3607f8f74fbbsalomon    GrGLRenderTarget* renderTarget = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
238571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (!renderTarget && !this->glCaps().canConfigBeFBOColorAttachment(surface->config())) {
23866cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon        return false;
23876cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    }
23886cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon
238916921ec30a81976129d507b1148c93a322e61a4fbsalomon    // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
2390e9573317d35d08254412eb407211f3607f8f74fbbsalomon    if (requires_srgb_conversion(surface->config(), config)) {
2391e9573317d35d08254412eb407211f3607f8f74fbbsalomon        return false;
2392e9573317d35d08254412eb407211f3607f8f74fbbsalomon    }
2393e9573317d35d08254412eb407211f3607f8f74fbbsalomon
2394e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // We have a special case fallback for reading eight bit alpha. We will read back all four 8
2395e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // bit channels as RGBA and then extract A.
239671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (!this->readPixelsSupported(surface, config)) {
2397e9573317d35d08254412eb407211f3607f8f74fbbsalomon        // Don't attempt to do any srgb conversions since we only care about alpha.
2398e9573317d35d08254412eb407211f3607f8f74fbbsalomon        GrPixelConfig tempConfig = kRGBA_8888_GrPixelConfig;
239971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        if (GrPixelConfigIsSRGB(surface->config())) {
2400e9573317d35d08254412eb407211f3607f8f74fbbsalomon            tempConfig = kSRGBA_8888_GrPixelConfig;
2401e9573317d35d08254412eb407211f3607f8f74fbbsalomon        }
2402e9573317d35d08254412eb407211f3607f8f74fbbsalomon        if (kAlpha_8_GrPixelConfig == config &&
240371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            this->readPixelsSupported(surface, tempConfig)) {
24047ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner            std::unique_ptr<uint32_t[]> temp(new uint32_t[width * height * 4]);
240571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            if (this->onReadPixels(surface, left, top, width, height, tempConfig, temp.get(),
2406e9573317d35d08254412eb407211f3607f8f74fbbsalomon                                   width*4)) {
2407e9573317d35d08254412eb407211f3607f8f74fbbsalomon                uint8_t* dst = reinterpret_cast<uint8_t*>(buffer);
2408e9573317d35d08254412eb407211f3607f8f74fbbsalomon                for (int j = 0; j < height; ++j) {
2409e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    for (int i = 0; i < width; ++i) {
2410e9573317d35d08254412eb407211f3607f8f74fbbsalomon                        dst[j*rowBytes + i] = (0xFF000000U & temp[j*width+i]) >> 24;
2411e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    }
2412e9573317d35d08254412eb407211f3607f8f74fbbsalomon                }
2413e9573317d35d08254412eb407211f3607f8f74fbbsalomon                return true;
2414e9573317d35d08254412eb407211f3607f8f74fbbsalomon            }
2415e9573317d35d08254412eb407211f3607f8f74fbbsalomon        }
241616921ec30a81976129d507b1148c93a322e61a4fbsalomon        return false;
241716921ec30a81976129d507b1148c93a322e61a4fbsalomon    }
241816921ec30a81976129d507b1148c93a322e61a4fbsalomon
241976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum externalFormat;
242076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum externalType;
242171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (!this->glCaps().getReadPixelsFormat(surface->config(), config, &externalFormat,
242276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                                            &externalType)) {
242376148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        return false;
242476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    }
24256cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon    bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
2426c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
242771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    GrGLIRect glvp;
242871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (renderTarget) {
242971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        // resolve the render target if necessary
243071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        switch (renderTarget->getResolveType()) {
243171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            case GrGLRenderTarget::kCantResolve_ResolveType:
243271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                return false;
243371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            case GrGLRenderTarget::kAutoResolves_ResolveType:
243471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                this->flushRenderTarget(renderTarget, &SkIRect::EmptyIRect());
243571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                break;
243671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            case GrGLRenderTarget::kCanResolve_ResolveType:
243771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                this->onResolveRenderTarget(renderTarget);
243871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                // we don't track the state of the READ FBO ID.
243971d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                fStats.incRenderTargetBinds();
244071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID()));
244171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                break;
244271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon            default:
244371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                SkFAIL("Unknown resolve type");
244471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        }
244571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        glvp = renderTarget->getViewport();
244671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    } else {
244771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        // Use a temporary FBO.
244871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        this->bindSurfaceFBOForPixelOps(surface, GR_GL_FRAMEBUFFER, &glvp, kSrc_TempFBOTarget);
2449294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        fHWBoundRenderTargetUniqueID.makeInvalid();
24506ba6fa15261be591f33cf0e5df7134e4fc6432acbsalomon    }
2451ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
24528895a7a0e222de4530e506e43eaa5e6030e8c5edbsalomon@google.com    // the read rect is viewport-relative
24538895a7a0e222de4530e506e43eaa5e6030e8c5edbsalomon@google.com    GrGLIRect readRect;
245471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    readRect.setRelativeTo(glvp, left, top, width, height, surface->origin());
2455fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
24569d02b264b72be64702e43cb797b7899a8a6926cabsalomon    size_t bytesPerPixel = GrBytesPerPixel(config);
24579d02b264b72be64702e43cb797b7899a8a6926cabsalomon    size_t tightRowBytes = bytesPerPixel * width;
24586d901da0ec4b10010eca05114ab8f9564bd04af3egdaniel
2459c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    size_t readDstRowBytes = tightRowBytes;
2460c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    void* readDst = buffer;
2461fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2462c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    // determine if GL can read using the passed rowBytes or if we need
2463c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    // a scratch buffer.
246429f8679068ecbd693e123a59b09a5ade3cfde996joshualitt    SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
2465c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    if (rowBytes != tightRowBytes) {
24669d02b264b72be64702e43cb797b7899a8a6926cabsalomon        if (this->glCaps().packRowLengthSupport() && !(rowBytes % bytesPerPixel)) {
24674677acc75915ebd32ee0efed5c7b41da2a9d047cskia.committer@gmail.com            GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH,
24689d02b264b72be64702e43cb797b7899a8a6926cabsalomon                                static_cast<GrGLint>(rowBytes / bytesPerPixel)));
2469c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            readDstRowBytes = rowBytes;
2470c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        } else {
2471c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            scratch.reset(tightRowBytes * height);
2472c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            readDst = scratch.get();
2473c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        }
2474c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
24753cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    if (flipY && this->glCaps().packFlipYSupport()) {
247656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1));
247756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com    }
2478f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon    GL_CALL(PixelStorei(GR_GL_PACK_ALIGNMENT, config_alignment(config)));
2479f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon
24800b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
24810b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                       readRect.fWidth, readRect.fHeight,
248276148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                       externalFormat, externalType, readDst));
2483c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    if (readDstRowBytes != tightRowBytes) {
2484f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(this->glCaps().packRowLengthSupport());
2485c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
2486c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
24873cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    if (flipY && this->glCaps().packFlipYSupport()) {
248856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0));
24893cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org        flipY = false;
249056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com    }
2491ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2492ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    // now reverse the order of the rows, since GL's are bottom-to-top, but our
2493c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    // API presents top-to-bottom. We must preserve the padding contents. Note
2494c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    // that the above readPixels did not overwrite the padding.
2495c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    if (readDst == buffer) {
2496f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(rowBytes == readDstRowBytes);
24973cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org        if (flipY) {
2498c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            scratch.reset(tightRowBytes);
2499c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            void* tmpRow = scratch.get();
2500c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            // flip y in-place by rows
2501c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            const int halfY = height >> 1;
2502c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            char* top = reinterpret_cast<char*>(buffer);
2503c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            char* bottom = top + (height - 1) * rowBytes;
2504c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            for (int y = 0; y < halfY; y++) {
2505c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                memcpy(tmpRow, top, tightRowBytes);
2506c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                memcpy(top, bottom, tightRowBytes);
2507c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                memcpy(bottom, tmpRow, tightRowBytes);
2508c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                top += rowBytes;
2509c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                bottom -= rowBytes;
2510c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            }
2511c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        }
2512c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    } else {
25139d02b264b72be64702e43cb797b7899a8a6926cabsalomon        SkASSERT(readDst != buffer);
25149d02b264b72be64702e43cb797b7899a8a6926cabsalomon        SkASSERT(rowBytes != tightRowBytes);
2515c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // copy from readDst to buffer while flipping y
2516cf6285b89b8820641ffb6871d4b3275bfe783f51caryclark@google.com        // const int halfY = height >> 1;
2517c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        const char* src = reinterpret_cast<const char*>(readDst);
2518c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        char* dst = reinterpret_cast<char*>(buffer);
25193cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org        if (flipY) {
2520c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            dst += (height-1) * rowBytes;
2521c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        }
2522c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        for (int y = 0; y < height; y++) {
2523c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            memcpy(dst, src, tightRowBytes);
2524c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            src += readDstRowBytes;
25253cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org            if (!flipY) {
2526c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                dst += rowBytes;
2527c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            } else {
2528c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                dst -= rowBytes;
2529c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            }
2530ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
2531ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
253271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (!renderTarget) {
253371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, surface);
253471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    }
2535ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return true;
2536ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2537ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
25389cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpuCommandBuffer* GrGLGpu::createCommandBuffer(
25399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
25409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) {
2541c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    return new GrGLGpuCommandBuffer(this);
2542066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
2543066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
254464d094d7756534a9b9b0997aab225d9ceba098b6brianosmanvoid GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bounds, bool disableSRGB) {
2545d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    SkASSERT(target);
25462e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2547294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    GrGpuResource::UniqueID rtID = target->uniqueID();
2548d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (fHWBoundRenderTargetUniqueID != rtID) {
25491e0bf7e113f994a512a351cc2b25ddb1e742b7d4bsalomon        fStats.incRenderTargetBinds();
2550d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
2551d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel#ifdef SK_DEBUG
2552d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        // don't do this check in Chromium -- this is causing
2553d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        // lots of repeated command buffer flushes when the compositor is
2554d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        // rendering with Ganesh, which is really slow; even too slow for
2555d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        // Debug mode.
25561acea86914797bc33856ff62b5cdfbe82c58dd67cdalton        if (kChromium_GrGLDriver != this->glContext().driver()) {
2557d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            GrGLenum status;
2558d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
2559d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
2560d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel                SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x\n", status);
2561d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            }
2562d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        }
2563d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel#endif
2564d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        fHWBoundRenderTargetUniqueID = rtID;
2565083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon        this->flushViewport(target->getViewport());
256664d094d7756534a9b9b0997aab225d9ceba098b6brianosman    }
256764d094d7756534a9b9b0997aab225d9ceba098b6brianosman
256835b784d48f59be3a3ee28d9d73e03c7f8835d2f9brianosman    if (this->glCaps().srgbWriteControl()) {
256933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !disableSRGB);
25701e0bf7e113f994a512a351cc2b25ddb1e742b7d4bsalomon    }
257164d094d7756534a9b9b0997aab225d9ceba098b6brianosman
2572083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    this->didWriteToSurface(target, bounds);
2573083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon}
2574083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon
257533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosmanvoid GrGLGpu::flushFramebufferSRGB(bool enable) {
257633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (enable && kYes_TriState != fHWSRGBFramebuffer) {
257733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB));
257833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        fHWSRGBFramebuffer = kYes_TriState;
257933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) {
258033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB));
258133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        fHWSRGBFramebuffer = kNo_TriState;
258233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
258333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman}
258433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
2585083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomonvoid GrGLGpu::flushViewport(const GrGLIRect& viewport) {
2586083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    if (fHWViewport != viewport) {
2587083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon        viewport.pushToGLViewport(this->glInterface());
2588083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon        fHWViewport = viewport;
2589083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    }
2590083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon}
2591a9909121ebdd35fb8d8694103a443f230ffa3a3absalomon
25920f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.comGrGLenum gPrimitiveType2GLMode[] = {
25930f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_TRIANGLES,
25940f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_TRIANGLE_STRIP,
25950f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_TRIANGLE_FAN,
25960f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_POINTS,
25970f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_LINES,
25980f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    GR_GL_LINE_STRIP
2599ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com};
2600ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2601d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#define SWAP_PER_DRAW 0
2602d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
2603a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com#if SWAP_PER_DRAW
26044382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org    #if defined(SK_BUILD_FOR_MAC)
2605d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        #include <AGL/agl.h>
26064382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org    #elif defined(SK_BUILD_FOR_WIN32)
2607ce7357df6aa2d73c6e74313af767db7b608fe0a5bsalomon@google.com        #include <gl/GL.h>
2608d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        void SwapBuf() {
2609d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            DWORD procID = GetCurrentProcessId();
2610d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            HWND hwnd = GetTopWindow(GetDesktopWindow());
2611d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            while(hwnd) {
2612d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                DWORD wndProcID = 0;
2613d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                GetWindowThreadProcessId(hwnd, &wndProcID);
2614d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                if(wndProcID == procID) {
2615d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                    SwapBuffers(GetDC(hwnd));
2616d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                }
2617d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
2618d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            }
2619d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com         }
2620d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    #endif
2621d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#endif
2622d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
26239cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrGLGpu::draw(const GrPipeline& pipeline,
26249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                   const GrPrimitiveProcessor& primProc,
26252eda5b3a65f54105ae3776160373eed5500c515fbsalomon                   const GrMesh meshes[],
26269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                   int meshCount) {
26279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    this->handleDirtyContext();
26289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
26292eda5b3a65f54105ae3776160373eed5500c515fbsalomon    bool hasPoints = false;
26302eda5b3a65f54105ae3776160373eed5500c515fbsalomon    for (int i = 0; i < meshCount; ++i) {
26312eda5b3a65f54105ae3776160373eed5500c515fbsalomon        if (meshes[i].primitiveType() == kPoints_GrPrimitiveType) {
26322eda5b3a65f54105ae3776160373eed5500c515fbsalomon            hasPoints = true;
26332eda5b3a65f54105ae3776160373eed5500c515fbsalomon            break;
26342eda5b3a65f54105ae3776160373eed5500c515fbsalomon        }
26352eda5b3a65f54105ae3776160373eed5500c515fbsalomon    }
26362eda5b3a65f54105ae3776160373eed5500c515fbsalomon    if (!this->flushGLState(pipeline, primProc, hasPoints)) {
2637d95263c60e1c3b9e337d777d6f3cf286c1dc43f6bsalomon        return;
2638d95263c60e1c3b9e337d777d6f3cf286c1dc43f6bsalomon    }
26392279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas
26400e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel    for (int i = 0; i < meshCount; ++i) {
26410e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) {
26420e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel            this->xferBarrier(pipeline.getRenderTarget(), barrierType);
26430e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        }
26440e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel
26450e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        const GrMesh& mesh = meshes[i];
26460e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        GrMesh::Iterator iter;
2647fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon        const GrNonInstancedMesh* nonInstMesh = iter.init(mesh);
26480e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel        do {
26490e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel            size_t indexOffsetInBytes = 0;
2650fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon            this->setupGeometry(primProc, *nonInstMesh, &indexOffsetInBytes);
2651fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon            if (nonInstMesh->isIndexed()) {
26520e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel                GrGLvoid* indices =
2653fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                    reinterpret_cast<GrGLvoid*>(indexOffsetInBytes +
2654fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                                sizeof(uint16_t) * nonInstMesh->startIndex());
26550e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel                // info.startVertex() was accounted for by setupGeometry.
2656fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                if (this->glCaps().drawRangeElementsSupport()) {
265709d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon                    // We assume here that the GrMeshDrawOps that generated the mesh used the full
2658fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                    // 0..vertexCount()-1 range.
2659fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                    int start = 0;
2660fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                    int end = nonInstMesh->vertexCount() - 1;
2661fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                    GL_CALL(DrawRangeElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
2662fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                              start, end,
2663fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                              nonInstMesh->indexCount(),
2664fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                              GR_GL_UNSIGNED_SHORT,
2665fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                              indices));
2666fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                } else {
2667fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                    GL_CALL(DrawElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
2668fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                         nonInstMesh->indexCount(),
2669fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                         GR_GL_UNSIGNED_SHORT,
2670fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                         indices));
2671fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                }
26720e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel            } else {
26730e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel                // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account
26740e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel                // for startVertex in the DrawElements case. So we always rely on setupGeometry to
26750e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel                // have accounted for startVertex.
2676fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonInstMesh->primitiveType()], 0,
2677fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon                                   nonInstMesh->vertexCount()));
26780e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel            }
26790e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel            fStats.incNumDraws();
2680fc9527a0dfab9b4e2f6c1b8a7ff23a61a5e6b31fbsalomon        } while ((nonInstMesh = iter.next()));
268174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    }
26822279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas
2683d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#if SWAP_PER_DRAW
2684d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    glFlush();
26854382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org    #if defined(SK_BUILD_FOR_MAC)
2686d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        aglSwapBuffers(aglGetCurrentContext());
2687d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        int set_a_break_pt_here = 9;
2688d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        aglSwapBuffers(aglGetCurrentContext());
26894382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org    #elif defined(SK_BUILD_FOR_WIN32)
2690d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        SwapBuf();
2691d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        int set_a_break_pt_here = 9;
2692d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        SwapBuf();
2693d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    #endif
2694d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#endif
2695ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2696ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2697861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
269875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
26995877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com    if (rt->needsResolve()) {
2700347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com        // Some extensions automatically resolves the texture when it is read.
2701347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com        if (this->glCaps().usesMSAARenderBuffers()) {
2702d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            SkASSERT(rt->textureFBOID() != rt->renderFBOID());
2703d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            fStats.incRenderTargetBinds();
2704d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            fStats.incRenderTargetBinds();
2705d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
2706d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
2707d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            // make sure we go through flushRenderTarget() since we've modified
2708d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            // the bound DRAW FBO ID.
2709294870ff119b89fc902773643b054f14e5d1f554Robert Phillips            fHWBoundRenderTargetUniqueID.makeInvalid();
2710f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com            const GrGLIRect& vp = rt->getViewport();
2711fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org            const SkIRect dirtyRect = rt->getResolveRect();
2712f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com
2713347c382d580cd1bc223e11a355b6a1c65d206e34bsalomon@google.com            if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
2714f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com                // Apple's extension uses the scissor as the blit bounds.
27153e79124a69d4806f0a1a776090bff718e1b90970bsalomon                GrScissorState scissorState;
2716e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips                scissorState.set(dirtyRect);
2717e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips                this->flushScissor(scissorState, vp, rt->origin());
271828341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton                this->disableWindowRectangles();
2719f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com                GL_CALL(ResolveMultisampleFramebuffer());
2720f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com            } else {
2721e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                int l, b, r, t;
2722e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag &
2723e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    this->glCaps().blitFramebufferSupportFlags()) {
2724e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    l = 0;
2725e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    b = 0;
2726e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    r = target->width();
2727e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    t = target->height();
2728e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                } else {
2729e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    GrGLIRect rect;
2730e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    rect.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
2731e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                                       dirtyRect.width(), dirtyRect.height(), target->origin());
2732e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    l = rect.fLeft;
2733e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    b = rect.fBottom;
2734e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    r = rect.fLeft + rect.fWidth;
2735e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                    t = rect.fBottom + rect.fHeight;
2736e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                }
27378c8f71ac07f0611d2c3ec53551c7e0f6a1cc4789derekf
27388c8f71ac07f0611d2c3ec53551c7e0f6a1cc4789derekf                // BlitFrameBuffer respects the scissor, so disable it.
273977b1307c1f5dac019575a6d431d5ce657370c4fbjoshualitt                this->disableScissor();
274028341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton                this->disableWindowRectangles();
2741e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t,
2742f3a60c09b975f50bbd14215df10effffd2fd46e8bsalomon@google.com                                        GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
2743a9ecdadfbcc06ccfd40f13aa2d7b563a64520060bsalomon@google.com            }
2744ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
27455877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com        rt->flagAsResolved();
2746ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
2747ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2748ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2749411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.comnamespace {
2750411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com
2751411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com
2752411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.comGrGLenum gr_to_gl_stencil_op(GrStencilOp op) {
275393a379bd4d6b30d86c270b879cf172d80172a72bcdalton    static const GrGLenum gTable[kGrStencilOpCount] = {
275493a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_KEEP,        // kKeep
275593a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_ZERO,        // kZero
275693a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_REPLACE,     // kReplace
275793a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_INVERT,      // kInvert
275893a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_INCR_WRAP,   // kIncWrap
275993a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_DECR_WRAP,   // kDecWrap
276093a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_INCR,        // kIncClamp
276193a379bd4d6b30d86c270b879cf172d80172a72bcdalton        GR_GL_DECR,        // kDecClamp
2762411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com    };
276393a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(0 == (int)GrStencilOp::kKeep);
276493a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(1 == (int)GrStencilOp::kZero);
276593a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(2 == (int)GrStencilOp::kReplace);
276693a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(3 == (int)GrStencilOp::kInvert);
276793a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(4 == (int)GrStencilOp::kIncWrap);
276893a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(5 == (int)GrStencilOp::kDecWrap);
276993a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(6 == (int)GrStencilOp::kIncClamp);
277093a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GR_STATIC_ASSERT(7 == (int)GrStencilOp::kDecClamp);
277193a379bd4d6b30d86c270b879cf172d80172a72bcdalton    SkASSERT(op < (GrStencilOp)kGrStencilOpCount);
277293a379bd4d6b30d86c270b879cf172d80172a72bcdalton    return gTable[(int)op];
2773411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com}
2774411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com
2775411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.comvoid set_gl_stencil(const GrGLInterface* gl,
277693a379bd4d6b30d86c270b879cf172d80172a72bcdalton                    const GrStencilSettings::Face& face,
277793a379bd4d6b30d86c270b879cf172d80172a72bcdalton                    GrGLenum glFace) {
277893a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GrGLenum glFunc = GrToGLStencilFunc(face.fTest);
277993a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GrGLenum glFailOp = gr_to_gl_stencil_op(face.fFailOp);
278093a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GrGLenum glPassOp = gr_to_gl_stencil_op(face.fPassOp);
2781a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com
278293a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GrGLint ref = face.fRef;
278393a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GrGLint mask = face.fTestMask;
278493a379bd4d6b30d86c270b879cf172d80172a72bcdalton    GrGLint writeMask = face.fWriteMask;
2785411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com
2786411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com    if (GR_GL_FRONT_AND_BACK == glFace) {
2787411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com        // we call the combined func just in case separate stencil is not
2788411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com        // supported.
2789411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com        GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask));
2790411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com        GR_GL_CALL(gl, StencilMask(writeMask));
2791c5d58f07aa6f4c47337d769e0e2e69c79669f91avbuzinov        GR_GL_CALL(gl, StencilOp(glFailOp, GR_GL_KEEP, glPassOp));
2792411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com    } else {
2793411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com        GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask));
2794411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com        GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask));
2795c5d58f07aa6f4c47337d769e0e2e69c79669f91avbuzinov        GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, GR_GL_KEEP, glPassOp));
2796411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com    }
2797411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com}
2798411dad0630913fc07f2412b4be17acfbfd914fbcbsalomon@google.com}
2799d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
28003e79124a69d4806f0a1a776090bff718e1b90970bsalomonvoid GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings) {
2801c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton    if (stencilSettings.isDisabled()) {
2802c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton        this->disableStencil();
2803c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton    } else if (fHWStencilSettings != stencilSettings) {
2804c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton        if (kYes_TriState != fHWStencilTestEnabled) {
2805c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton            GL_CALL(Enable(GR_GL_STENCIL_TEST));
2806c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton            fHWStencilTestEnabled = kYes_TriState;
2807a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com        }
2808c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton        if (stencilSettings.isTwoSided()) {
2809c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton            SkASSERT(this->caps()->twoSidedStencilSupport());
2810c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton            set_gl_stencil(this->glInterface(),
2811c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton                           stencilSettings.front(),
2812c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton                           GR_GL_FRONT);
2813c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton            set_gl_stencil(this->glInterface(),
2814c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton                           stencilSettings.back(),
2815c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton                           GR_GL_BACK);
2816c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton        } else {
2817c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton            set_gl_stencil(this->glInterface(),
2818c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton                           stencilSettings.front(),
2819c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton                           GR_GL_FRONT_AND_BACK);
2820ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
2821a58fe35fdae3481cf43062f7032820c320c3d163joshualitt        fHWStencilSettings = stencilSettings;
2822ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
2823ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
2824ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2825c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdaltonvoid GrGLGpu::disableStencil() {
2826c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton    if (kNo_TriState != fHWStencilTestEnabled) {
2827c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton        GL_CALL(Disable(GR_GL_STENCIL_TEST));
2828c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton        fHWStencilTestEnabled = kNo_TriState;
2829c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton        fHWStencilSettings.invalidate();
2830c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton    }
2831c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton}
2832c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton
2833af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdaltonvoid GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled) {
2834083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    // rt is only optional if useHWAA is false.
2835083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    SkASSERT(rt || !useHWAA);
2836dded69693dd3779f081326cde24c3954505b129dvbuzinov    SkASSERT(!useHWAA || rt->isStencilBufferMultisampled());
2837202d139452bed846a81cd89bbb3808ded0b3d64fbsalomon@google.com
28382b5f2cbf0d0b580e5277d1d085ce261cb5233111csmartdalton    if (this->caps()->multisampleDisableSupport()) {
2839d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton        if (useHWAA) {
2840d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton            if (kYes_TriState != fMSAAEnabled) {
2841d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton                GL_CALL(Enable(GR_GL_MULTISAMPLE));
2842d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton                fMSAAEnabled = kYes_TriState;
2843d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton            }
2844d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton        } else {
2845d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton            if (kNo_TriState != fMSAAEnabled) {
2846d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton                GL_CALL(Disable(GR_GL_MULTISAMPLE));
2847d0a840d4d8bb6ebc9981cc331b1b231a6c6e0928cdalton                fMSAAEnabled = kNo_TriState;
2848f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com            }
2849f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com        }
2850f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com    }
2851af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton
2852af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton    if (0 != this->caps()->maxRasterSamples()) {
2853f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton        if (useHWAA && rt->isMixedSampled() && !stencilEnabled) {
2854af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            // Since stencil is disabled and we want more samples than are in the color buffer, we
2855af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            // need to tell the rasterizer explicitly how many to run.
2856af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            if (kYes_TriState != fHWRasterMultisampleEnabled) {
2857af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                GL_CALL(Enable(GR_GL_RASTER_MULTISAMPLE));
2858af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                fHWRasterMultisampleEnabled = kYes_TriState;
2859af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            }
2860af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            if (rt->numStencilSamples() != fHWNumRasterSamples) {
2861af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                SkASSERT(rt->numStencilSamples() <= this->caps()->maxRasterSamples());
2862af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                GL_CALL(RasterSamples(rt->numStencilSamples(), GR_GL_TRUE));
2863af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                fHWNumRasterSamples = rt->numStencilSamples();
2864af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            }
2865af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton        } else {
2866af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            if (kNo_TriState != fHWRasterMultisampleEnabled) {
2867af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                GL_CALL(Disable(GR_GL_RASTER_MULTISAMPLE));
2868af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton                fHWRasterMultisampleEnabled = kNo_TriState;
2869af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton            }
2870af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton        }
2871af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton    } else {
2872f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton        SkASSERT(!useHWAA || !rt->isMixedSampled() || stencilEnabled);
2873af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton    }
2874f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com}
2875f954d8dd9a4e75aa97e7da79692f5a7add039e68bsalomon@google.com
28767f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomonvoid GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) {
2877b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel    // Any optimization to disable blending should have already been applied and
28788917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    // tweaked the equation to "add" or "subtract", and the coeffs to (1, 0).
2879f7cc87719e53df86784d0d953b88c45a3be38953bsalomon
28808917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    GrBlendEquation equation = blendInfo.fEquation;
2881c230414861558ce20b74281b1ca363e56c441832egdaniel    GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
2882c230414861558ce20b74281b1ca363e56c441832egdaniel    GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
28838917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) &&
28848917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton                    kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
2885b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel    if (blendOff) {
2886b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel        if (kNo_TriState != fHWBlendState.fEnabled) {
2887b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel            GL_CALL(Disable(GR_GL_BLEND));
28889764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang
28899764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang            // Workaround for the ARM KHR_blend_equation_advanced blacklist issue
28909764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang            // https://code.google.com/p/skia/issues/detail?id=3943
28919764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang            if (kARM_GrGLVendor == this->ctxInfo().vendor() &&
28929764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang                GrBlendEquationIsAdvanced(fHWBlendState.fEquation)) {
28939764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang                SkASSERT(this->caps()->advancedBlendEquationSupport());
28949764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang                // Set to any basic blending equation.
28959764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang                GrBlendEquation blend_equation = kAdd_GrBlendEquation;
28969764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang                GL_CALL(BlendEquation(gXfermodeEquation2Blend[blend_equation]));
28979764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang                fHWBlendState.fEquation = blend_equation;
28989764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang            }
28999764c40cd31c11c82686c8b8dbbeaea9fa4de05djoel.liang
2900b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel            fHWBlendState.fEnabled = kNo_TriState;
2901b414f25cf97a690034a180a2c704b4b3935b8ed0egdaniel        }
29028917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        return;
29038917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    }
29048917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton
29058917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    if (kYes_TriState != fHWBlendState.fEnabled) {
29068917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        GL_CALL(Enable(GR_GL_BLEND));
29078917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        fHWBlendState.fEnabled = kYes_TriState;
29088917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    }
29098917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton
29108917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    if (fHWBlendState.fEquation != equation) {
29118917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        GL_CALL(BlendEquation(gXfermodeEquation2Blend[equation]));
29128917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        fHWBlendState.fEquation = equation;
29138917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    }
29148917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton
29158917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    if (GrBlendEquationIsAdvanced(equation)) {
29168917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        SkASSERT(this->caps()->advancedBlendEquationSupport());
29178917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        // Advanced equations have no other blend state.
29188917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        return;
29198917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    }
29208917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton
2921e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon    if (fHWBlendState.fSrcCoeff != srcCoeff || fHWBlendState.fDstCoeff != dstCoeff) {
29228917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
29238917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton                          gXfermodeCoeff2Blend[dstCoeff]));
29248917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        fHWBlendState.fSrcCoeff = srcCoeff;
29258917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        fHWBlendState.fDstCoeff = dstCoeff;
29268917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton    }
29278917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton
29287f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff))) {
29297f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        GrColor blendConst = blendInfo.fBlendConstant;
29307f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        blendConst = swizzle.applyTo(blendConst);
29317f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        if (!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst) {
29327f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon            GrGLfloat c[4];
29337f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon            GrColorToRGBAFloat(blendConst, c);
29347f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon            GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
29357f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon            fHWBlendState.fConstColor = blendConst;
29367f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon            fHWBlendState.fConstColorValid = true;
29377f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        }
29380650e811b537f21a3a9d09a953960626cf5cfce4bsalomon@google.com    }
29390650e811b537f21a3a9d09a953960626cf5cfce4bsalomon@google.com}
2940b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com
29416364b5edc3adb4ec0b26e507a474a2066977c509commit-bot@chromium.orgstatic inline GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) {
2942b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    static const GrGLenum gWrapModes[] = {
2943b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com        GR_GL_CLAMP_TO_EDGE,
2944b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com        GR_GL_REPEAT,
2945b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com        GR_GL_MIRRORED_REPEAT
2946b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    };
29475d7ca957edcc57f7f0be2741183e8d3c36cb5129commit-bot@chromium.org    GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes));
2948b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode);
2949b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode);
2950b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode);
2951b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    return gWrapModes[tm];
2952b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com}
2953b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com
2954b7e7d5748d74c7482436b33733d7770484bb62e3egdanielstatic GrGLenum get_component_enum_from_char(char component) {
2955b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel    switch (component) {
2956b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel        case 'r':
2957b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel           return GR_GL_RED;
2958b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel        case 'g':
2959b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel           return GR_GL_GREEN;
2960b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel        case 'b':
2961b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel           return GR_GL_BLUE;
2962b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel        case 'a':
2963b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel           return GR_GL_ALPHA;
2964b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel        default:
2965b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel            SkFAIL("Unsupported component");
2966b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel            return 0;
2967b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel    }
2968b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel}
2969b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel
2970b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel/** If texture swizzling is available using tex parameters then it is preferred over mangling
2971b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel  the generated shader code. This potentially allows greater reuse of cached shaders. */
2972b7e7d5748d74c7482436b33733d7770484bb62e3egdanielstatic void get_tex_param_swizzle(GrPixelConfig config,
2973cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon                                  const GrGLCaps& caps,
2974b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel                                  GrGLenum* glSwizzle) {
2975cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon    const GrSwizzle& swizzle = caps.configSwizzle(config);
2976b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel    for (int i = 0; i < 4; ++i) {
2977cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon        glSwizzle[i] = get_component_enum_from_char(swizzle.c_str()[i]);
2978574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel    }
2979574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel}
2980574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel
2981514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomonvoid GrGLGpu::bindTexture(int unitIdx, const GrSamplerParams& params, bool allowSRGBInputs,
2982a6359365887048ef055196de75591311d7a015f0brianosman                          GrGLTexture* texture) {
298349f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(texture);
2984d0c1a06cb98dd4a009dfa79e37ba6ca23a8c180btomhudson@google.com
2985856e9d921462136da8562f8f122d42e114cd4710reed#ifdef SK_DEBUG
2986856e9d921462136da8562f8f122d42e114cd4710reed    if (!this->caps()->npotTextureTileSupport()) {
2987856e9d921462136da8562f8f122d42e114cd4710reed        const bool tileX = SkShader::kClamp_TileMode != params.getTileModeX();
2988856e9d921462136da8562f8f122d42e114cd4710reed        const bool tileY = SkShader::kClamp_TileMode != params.getTileModeY();
2989856e9d921462136da8562f8f122d42e114cd4710reed        if (tileX || tileY) {
2990856e9d921462136da8562f8f122d42e114cd4710reed            const int w = texture->width();
2991856e9d921462136da8562f8f122d42e114cd4710reed            const int h = texture->height();
2992856e9d921462136da8562f8f122d42e114cd4710reed            SkASSERT(SkIsPow2(w) && SkIsPow2(h));
2993856e9d921462136da8562f8f122d42e114cd4710reed        }
2994856e9d921462136da8562f8f122d42e114cd4710reed    }
2995856e9d921462136da8562f8f122d42e114cd4710reed#endif
2996856e9d921462136da8562f8f122d42e114cd4710reed
2997b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    // If we created a rt/tex and rendered to it without using a texture and now we're texturing
2998b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    // from the rt it will still be the last bound texture, but it needs resolving. So keep this
29994c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    // out of the "last != next" check.
300037dd331b20a92ce79cc26556e065dec98a66cb0bbsalomon    GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget());
300149f085dddff10473b6ebf832a974288300224e60bsalomon    if (texRT) {
30024c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com        this->onResolveRenderTarget(texRT);
30034c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    }
30044c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com
3005294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    GrGpuResource::UniqueID textureID = texture->uniqueID();
300610528f1d5838ae1cac015024c4e8731484f888d1bsalomon    GrGLenum target = texture->target();
30071c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon    if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) {
300834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com        this->setTextureUnit(unitIdx);
300910528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GL_CALL(BindTexture(target, texture->textureID()));
30101c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon        fHWBoundTextureUniqueIDs[unitIdx] = textureID;
30114c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    }
30124c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com
30134c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    ResetTimestamp timestamp;
301434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&timestamp);
30154c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    bool setAll = timestamp < this->getResetTimestamp();
30164c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    GrGLTexture::TexParams newTexParams;
30174c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com
3018149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org    static GrGLenum glMinFilterModes[] = {
3019cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org        GR_GL_NEAREST,
3020cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org        GR_GL_LINEAR,
3021cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org        GR_GL_LINEAR_MIPMAP_LINEAR
3022cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org    };
3023149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org    static GrGLenum glMagFilterModes[] = {
3024149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org        GR_GL_NEAREST,
3025149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org        GR_GL_LINEAR,
3026149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org        GR_GL_LINEAR
3027149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org    };
3028514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    GrSamplerParams::FilterMode filterMode = params.filterMode();
3029efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon
3030514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    if (GrSamplerParams::kMipMap_FilterMode == filterMode) {
3031efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon        if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture->config())) {
3032514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon            filterMode = GrSamplerParams::kBilerp_FilterMode;
3033efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon        }
30344744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org    }
3035efd7d45fc0fc5f2b924c774c5d38ce546f35f3cabsalomon
30364744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org    newTexParams.fMinFilter = glMinFilterModes[filterMode];
30374744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org    newTexParams.fMagFilter = glMagFilterModes[filterMode];
3038aeefb2afe74c010c7236f3572e21a8f8a6aee1bdskia.committer@gmail.com
303920471894eaa441193d5ae8f2395e8244c91c55afbrianosman    if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) {
3040fe19987e5499650e8637a8d109f19b8156601660brianosman        newTexParams.fSRGBDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT;
304133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) {
3042adf4fa6fdef40071ebef11d767c2eb067af77179brianosman            this->setTextureUnit(unitIdx);
304333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexParams.fSRGBDecode));
304455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
3045cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org    }
30464c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com
304733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman#ifdef SK_DEBUG
304833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // We were supposed to ensure MipMaps were up-to-date and built correctly before getting here.
3049514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    if (GrSamplerParams::kMipMap_FilterMode == filterMode) {
305033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        SkASSERT(!texture->texturePriv().mipMapsAreDirty());
305133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        if (GrPixelConfigIsSRGB(texture->config())) {
30527b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman            SkDestinationSurfaceColorMode colorMode = allowSRGBInputs
30537b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman                ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
30547b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman                : SkDestinationSurfaceColorMode::kLegacy;
30557b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman            SkASSERT(texture->texturePriv().mipColorMode() == colorMode);
305633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
305733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
305833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman#endif
305933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
306055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel();
306155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
3062b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
3063b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com    newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
3064cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon    get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizzleRGBA);
3065149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org    if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
306634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com        this->setTextureUnit(unitIdx);
306710528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMagFilter));
3068149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org    }
3069149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org    if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) {
3070149f4f5b4013f3d28017fd548e43b69133be83c3commit-bot@chromium.org        this->setTextureUnit(unitIdx);
307110528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMinFilter));
30724c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    }
307355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (setAll || newTexParams.fMaxMipMapLevel != oldTexParams.fMaxMipMapLevel) {
307409bd2c09b6b36737df289fdb5fa38c280162cbb8cblume        // These are not supported in ES2 contexts
307509bd2c09b6b36737df289fdb5fa38c280162cbb8cblume        if (this->glCaps().mipMapLevelAndLodControlSupport()) {
307609bd2c09b6b36737df289fdb5fa38c280162cbb8cblume            if (newTexParams.fMaxMipMapLevel != 0) {
307709bd2c09b6b36737df289fdb5fa38c280162cbb8cblume                this->setTextureUnit(unitIdx);
307809bd2c09b6b36737df289fdb5fa38c280162cbb8cblume                GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0));
307909bd2c09b6b36737df289fdb5fa38c280162cbb8cblume                GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0));
308009bd2c09b6b36737df289fdb5fa38c280162cbb8cblume                GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LOD,
308109bd2c09b6b36737df289fdb5fa38c280162cbb8cblume                                      newTexParams.fMaxMipMapLevel));
308209bd2c09b6b36737df289fdb5fa38c280162cbb8cblume                GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL,
308309bd2c09b6b36737df289fdb5fa38c280162cbb8cblume                                      newTexParams.fMaxMipMapLevel));
308409bd2c09b6b36737df289fdb5fa38c280162cbb8cblume            }
308555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
308655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
30874c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
308834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com        this->setTextureUnit(unitIdx);
308910528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS));
30904c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    }
30914c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
309234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com        this->setTextureUnit(unitIdx);
309310528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT));
30944c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    }
3095cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon    if (this->glCaps().textureSwizzleSupport() &&
30964c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com        (setAll || memcmp(newTexParams.fSwizzleRGBA,
30974c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com                          oldTexParams.fSwizzleRGBA,
30984c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com                          sizeof(newTexParams.fSwizzleRGBA)))) {
309974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        this->setTextureSwizzle(unitIdx, target, newTexParams.fSwizzleRGBA);
31004c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com    }
310134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com    texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
31024c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com}
31034c8837867add05f8d25520f92f6ec52305dda02ebsalomon@google.com
31041897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdaltonvoid GrGLGpu::bindTexelBuffer(int unitIdx, GrPixelConfig texelConfig, GrGLBuffer* buffer) {
310574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    SkASSERT(this->glCaps().canUseConfigWithTexelBuffer(texelConfig));
310674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    SkASSERT(unitIdx >= 0 && unitIdx < fHWBufferTextures.count());
310774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
310874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    BufferTexture& buffTex = fHWBufferTextures[unitIdx];
310974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
311074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    if (!buffTex.fKnownBound) {
311174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        if (!buffTex.fTextureID) {
311274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            GL_CALL(GenTextures(1, &buffTex.fTextureID));
311374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            if (!buffTex.fTextureID) {
311474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                return;
311574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            }
311674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        }
311774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
311874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        this->setTextureUnit(unitIdx);
311974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID));
312074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
312174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        buffTex.fKnownBound = true;
312274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    }
312374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
31248abb370aca280516f4861c6c942ec453aad018farobertphillips    if (buffer->uniqueID() != buffTex.fAttachedBufferUniqueID ||
31251897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton        buffTex.fTexelConfig != texelConfig) {
312674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
312774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        this->setTextureUnit(unitIdx);
31281897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton        GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER,
31291897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton                          this->glCaps().configSizedInternalFormat(texelConfig),
31301897cfd7a6e193b42ca95e830e9485f5201a995ccsmartdalton                          buffer->bufferID()));
313174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
313274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        buffTex.fTexelConfig = texelConfig;
31338abb370aca280516f4861c6c942ec453aad018farobertphillips        buffTex.fAttachedBufferUniqueID = buffer->uniqueID();
313474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
313574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        if (this->glCaps().textureSwizzleSupport() &&
313674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            this->glCaps().configSwizzle(texelConfig) != buffTex.fSwizzle) {
313774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            GrGLenum glSwizzle[4];
313874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle);
313974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle);
314074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton            buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig);
314174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        }
314274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
314374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        buffer->setHasAttachedToTexture();
314474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUnit);
314574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    }
314674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton}
314774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
3148f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomonvoid GrGLGpu::bindImageStorage(int unitIdx, GrIOType ioType, GrGLTexture *texture) {
3149f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    SkASSERT(texture);
3150f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    if (texture->uniqueID() != fHWBoundImageStorages[unitIdx].fTextureUniqueID ||
3151f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon        ioType != fHWBoundImageStorages[unitIdx].fIOType) {
315294e4ab1e353f2202369798045ec3dfe0a89c9bbeJoe Gregorio        GrGLenum access = GR_GL_READ_ONLY;
3153f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon        switch (ioType) {
3154f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon            case kRead_GrIOType:
3155f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon                access = GR_GL_READ_ONLY;
3156f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon                break;
3157f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon            case kWrite_GrIOType:
3158f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon                access = GR_GL_WRITE_ONLY;
3159f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon                break;
3160f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon            case kRW_GrIOType:
3161f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon                access = GR_GL_READ_WRITE;
3162f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon                break;
3163f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon        }
3164f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon        GrGLenum format = this->glCaps().getImageFormat(texture->config());
3165f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon        GL_CALL(BindImageTexture(unitIdx, texture->textureID(), 0, GR_GL_FALSE, 0, access, format));
3166f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    }
3167f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon}
3168f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon
3169514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomonvoid GrGLGpu::generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs,
317033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                              GrGLTexture* texture) {
317133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    SkASSERT(texture);
317233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
317333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // First, figure out if we need mips for this texture at all:
3174514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    GrSamplerParams::FilterMode filterMode = params.filterMode();
317533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
3176514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    if (GrSamplerParams::kMipMap_FilterMode == filterMode) {
317733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture->config())) {
3178514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon            filterMode = GrSamplerParams::kBilerp_FilterMode;
317933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
318033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
318133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
3182514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    if (GrSamplerParams::kMipMap_FilterMode != filterMode) {
318333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return;
318433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
318533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
318633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // If this is an sRGB texture and the mips were previously built the "other" way
318733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // (gamma-correct vs. not), then we need to rebuild them. We don't need to check for
318833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // srgbSupport - we'll *never* get an sRGB pixel config if we don't support it.
31897b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman    SkDestinationSurfaceColorMode colorMode = allowSRGBInputs
31907b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
31917b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman        : SkDestinationSurfaceColorMode::kLegacy;
319233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (GrPixelConfigIsSRGB(texture->config()) &&
31937b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman        colorMode != texture->texturePriv().mipColorMode()) {
319433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        texture->texturePriv().dirtyMipMaps(true);
319533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
319633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
319733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // If the mips aren't dirty, we're done:
319833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (!texture->texturePriv().mipMapsAreDirty()) {
319933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return;
320033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
320133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
320233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // If we created a rt/tex and rendered to it without using a texture and now we're texturing
320333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // from the rt it will still be the last bound texture, but it needs resolving.
320433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget());
320533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (texRT) {
320633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        this->onResolveRenderTarget(texRT);
320733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
320833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
320933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrGLenum target = texture->target();
321033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    this->setScratchTextureUnit();
321133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL(BindTexture(target, texture->textureID()));
321233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
321333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Configure sRGB decode, if necessary. This state is the only thing needed for the driver
321433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // call (glGenerateMipmap) to work correctly. Our manual method dirties other state, too.
321520471894eaa441193d5ae8f2395e8244c91c55afbrianosman    if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) {
3216b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        GrGLenum srgbDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT;
3217b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        // Command buffer's sRGB decode extension doesn't influence mipmap generation correctly.
3218b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        // If we set this to skip_decode, it appears to suppress sRGB -> Linear for each downsample,
3219b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        // but not the Linear -> sRGB when writing the next level. The result is that mip-chains
3220b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        // get progressively brighter as you go down. Forcing this to 'decode' gives predictable
3221b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        // (and only slightly incorrect) results. See crbug.com/655247 (~comment 28)
3222b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        if (!this->glCaps().srgbDecodeDisableAffectsMipmaps()) {
3223b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman            srgbDecode = GR_GL_DECODE_EXT;
3224b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        }
3225b0403207cbeaaf3e79e92f8fbc026ca0de9c34ddBrian Osman        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, srgbDecode));
322633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
322733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
322833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Either do manual mipmap generation or (if that fails), just rely on the driver:
322933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (!this->generateMipmap(texture, allowSRGBInputs)) {
323033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(GenerateMipmap(target));
323133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
323233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
3233fe19987e5499650e8637a8d109f19b8156601660brianosman    texture->texturePriv().dirtyMipMaps(false);
323433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount(
323533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        texture->width(), texture->height()));
32367b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman    texture->texturePriv().setMipColorMode(colorMode);
323733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
323833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // We have potentially set lots of state on the texture. Easiest to dirty it all:
323933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    texture->textureParamsModified();
324033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman}
324133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
324274b8d323323c8533e3e5cc7719e0bd127aacd829cdaltonvoid GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]) {
324374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    this->setTextureUnit(unitIdx);
324474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    if (this->glStandard() == kGLES_GrGLStandard) {
324574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
324674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
324774b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
324874b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
324974b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
325074b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    } else {
325174b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint));
325274b8d323323c8533e3e5cc7719e0bd127aacd829cdalton        GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA,
325374b8d323323c8533e3e5cc7719e0bd127aacd829cdalton                               reinterpret_cast<const GrGLint*>(swizzle)));
325474b8d323323c8533e3e5cc7719e0bd127aacd829cdalton    }
325574b8d323323c8533e3e5cc7719e0bd127aacd829cdalton}
325674b8d323323c8533e3e5cc7719e0bd127aacd829cdalton
3257080e673b10ac607305f140ddb245e140ccde40c6egdanielvoid GrGLGpu::flushColorWrite(bool writeColor) {
3258080e673b10ac607305f140ddb245e140ccde40c6egdaniel    if (!writeColor) {
3259978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        if (kNo_TriState != fHWWriteToColor) {
3260978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com            GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
3261978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com                              GR_GL_FALSE, GR_GL_FALSE));
3262978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com            fHWWriteToColor = kNo_TriState;
3263978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        }
3264978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com    } else {
3265978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        if (kYes_TriState != fHWWriteToColor) {
3266978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com            GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
3267978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com            fHWWriteToColor = kYes_TriState;
3268d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        }
3269d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    }
32703e79124a69d4806f0a1a776090bff718e1b90970bsalomon}
3271d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
32725fa7f30331585f78cf0f81ac185abbff1fee1152robertphillipsvoid GrGLGpu::flushDrawFace(GrDrawFace face) {
32733e79124a69d4806f0a1a776090bff718e1b90970bsalomon    if (fHWDrawFace != face) {
32743e79124a69d4806f0a1a776090bff718e1b90970bsalomon        switch (face) {
32755fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips            case GrDrawFace::kCCW:
32760b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GL_CALL(Enable(GR_GL_CULL_FACE));
32770b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GL_CALL(CullFace(GR_GL_BACK));
3278d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                break;
32795fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips            case GrDrawFace::kCW:
32800b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GL_CALL(Enable(GR_GL_CULL_FACE));
32810b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GL_CALL(CullFace(GR_GL_FRONT));
3282d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                break;
32835fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips            case GrDrawFace::kBoth:
32840b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GL_CALL(Disable(GR_GL_CULL_FACE));
3285d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                break;
3286d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            default:
328788cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org                SkFAIL("Unknown draw face.");
3288d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        }
32893e79124a69d4806f0a1a776090bff718e1b90970bsalomon        fHWDrawFace = face;
3290d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    }
3291ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
3292ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3293861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::setTextureUnit(int unit) {
32941c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon    SkASSERT(unit >= 0 && unit < fHWBoundTextureUniqueIDs.count());
3295a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org    if (unit != fHWActiveTextureUnitIdx) {
32960b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
3297492093951ae2a7d7c14aa22f48faa8942f045cafbsalomon@google.com        fHWActiveTextureUnitIdx = unit;
32988531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
32998531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
3300316f9923cb265cea8d52aafeb28f959870124207bsalomon@google.com
3301861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLGpu::setScratchTextureUnit() {
3302a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org    // Bind the last texture unit since it is the least likely to be used by GrGLProgram.
33031c63bf6e90f160c9a0d7484dedfaf87c0aa341e9bsalomon    int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1;
3304a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org    if (lastUnitIdx != fHWActiveTextureUnitIdx) {
3305a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org        GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx));
3306a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org        fHWActiveTextureUnitIdx = lastUnitIdx;
33078531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
3308a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org    // clear out the this field so that if a program does use this unit it will rebind the correct
3309a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11accommit-bot@chromium.org    // texture.
3310294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    fHWBoundTextureUniqueIDs[lastUnitIdx].makeInvalid();
33118531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
33128531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
3313e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon// Determines whether glBlitFramebuffer could be used between src and dst by onCopySurface.
3314e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomonstatic inline bool can_blit_framebuffer_for_copy_surface(const GrSurface* dst,
3315e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                                                         const GrSurface* src,
3316e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                                                         const SkIRect& srcRect,
3317e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                                                         const SkIPoint& dstPoint,
3318e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon                                                         const GrGLGpu* gpu) {
3319e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    auto blitFramebufferFlags = gpu->glCaps().blitFramebufferSupportFlags();
332071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (!gpu->glCaps().canConfigBeFBOColorAttachment(dst->config()) ||
332171d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        !gpu->glCaps().canConfigBeFBOColorAttachment(src->config())) {
3322e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        return false;
3323e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3324bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // Blits are not allowed between int color buffers and float/fixed color buffers. GrGpu should
3325bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // have filtered such cases out.
3326bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    SkASSERT(GrPixelConfigIsSint(dst->config()) == GrPixelConfigIsSint(src->config()));
3327e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
3328e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(dst->asTexture());
3329e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    const GrRenderTarget* dstRT = dst->asRenderTarget();
3330e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    const GrRenderTarget* srcRT = src->asRenderTarget();
3331e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (dstTex && dstTex->target() != GR_GL_TEXTURE_2D) {
3332e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        return false;
3333e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3334e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (srcTex && srcTex->target() != GR_GL_TEXTURE_2D) {
3335e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        return false;
3336e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3337e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
3338e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        return false;
3339e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3340e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
3341e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        // We would mirror to compensate for origin changes. Note that copySurface is
3342e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        // specified such that the src and dst rects are the same.
3343e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        if (dst->origin() != src->origin()) {
3344e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon            return false;
3345a8e5a06f69b7e0cb17a4b3203f0a7a1d52aa73eccommit-bot@chromium.org        }
3346e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3347e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
3348e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        if (srcRT && srcRT->numColorSamples() && dstRT && !dstRT->numColorSamples()) {
33497ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon            return false;
33507ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        }
3351e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3352e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
3353e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        if (dstRT && dstRT->numColorSamples() > 0) {
3354e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon            return false;
3355e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        }
3356e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3357e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
3358e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        if (dst->config() != src->config()) {
3359e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon            return false;
3360e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        }
3361e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3362e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        const GrRenderTarget* srcRT = src->asRenderTarget();
3363e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        if (srcRT && srcRT->numColorSamples() && dst->config() != src->config()) {
33647ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon            return false;
33657ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        }
3366eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    }
3367e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3368e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        if (srcRT && srcRT->numColorSamples() &&
3369e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon            (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop)) {
3370e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon            return false;
3371e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon        }
3372e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    }
3373e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    return true;
337463150afcc0c4120370db6f5566cd404584345668commit-bot@chromium.org}
3375eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com
33767ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomonstatic inline bool can_copy_texsubimage(const GrSurface* dst,
33777ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon                                        const GrSurface* src,
33787ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon                                        const GrGLGpu* gpu) {
3379eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3380eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
3381eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    // many drivers would allow it to work, but ANGLE does not.
33829e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org    if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalFormat() &&
3383eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig == src->config())) {
3384eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        return false;
3385eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    }
3386eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget());
3387eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer)
3388eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    // then we don't want to copy to the texture but to the MSAA buffer.
3389d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) {
3390eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        return false;
3391eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    }
3392a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com    const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
3393a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com    // If the src is multisampled (and uses an extension where there is a separate MSAA
3394a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com    // renderbuffer) then it is an invalid operation to call CopyTexSubImage
3395d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel    if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
3396a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com        return false;
3397a2719855ba80516a0b387777004a0da6049f3d68bsalomon@google.com    }
33987ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
33997ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
34007ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
34017ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    // texture.
34027ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (!dstTex) {
34037ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return false;
34047ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
34057ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
34067ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture());
34076121405df5689875c7309c20632a82897fce4127cblume
34087ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
34097ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    // is required.
341071d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (gpu->glCaps().canConfigBeFBOColorAttachment(src->config()) &&
34117ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        !GrPixelConfigIsCompressed(src->config()) &&
341271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon        (!srcTex || srcTex->target() == GR_GL_TEXTURE_2D) && dstTex->target() == GR_GL_TEXTURE_2D &&
34137ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        dst->origin() == src->origin()) {
3414eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        return true;
3415eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    } else {
3416eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        return false;
3417eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    }
3418eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com}
3419eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com
3420eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
3421eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com// relative to is output.
342271d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomonvoid GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
342371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon                                        TempFBOTarget tempFBOTarget) {
3424eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
3425083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    if (!rt) {
342649f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(surface->asTexture());
3427eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID();
342810528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GrGLenum target = static_cast<GrGLTexture*>(surface->asTexture())->target();
3429d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GrGLuint* tempFBOID;
3430d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTempDstFBOID;
34310f5f967f6777612353c762e6d0095f733adfb326egdaniel
3432d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        if (0 == *tempFBOID) {
3433d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel            GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID));
34340f5f967f6777612353c762e6d0095f733adfb326egdaniel        }
34350f5f967f6777612353c762e6d0095f733adfb326egdaniel
3436d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        fStats.incRenderTargetBinds();
3437d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID));
3438d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
3439754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips                                                             GR_GL_COLOR_ATTACHMENT0,
344010528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                                             target,
3441754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips                                                             texID,
3442754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips                                                             0));
3443eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        viewport->fLeft = 0;
3444eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        viewport->fBottom = 0;
3445eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        viewport->fWidth = surface->width();
3446eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        viewport->fHeight = surface->height();
3447eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    } else {
3448d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        fStats.incRenderTargetBinds();
3449d803f2731f778317b46da64bce6e7a8a221ffccdegdaniel        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
3450eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        *viewport = rt->getViewport();
3451eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    }
34520f5f967f6777612353c762e6d0095f733adfb326egdaniel}
34530f5f967f6777612353c762e6d0095f733adfb326egdaniel
345471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomonvoid GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface) {
345571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    // bindSurfaceFBOForPixelOps temporarily binds textures that are not render targets to
345610528f1d5838ae1cac015024c4e8731484f888d1bsalomon    if (!surface->asRenderTarget()) {
345710528f1d5838ae1cac015024c4e8731484f888d1bsalomon        SkASSERT(surface->asTexture());
345810528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())->target();
345910528f1d5838ae1cac015024c4e8731484f888d1bsalomon        GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
346010528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                                             GR_GL_COLOR_ATTACHMENT0,
346110528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                                             textureTarget,
346210528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                                             0,
346310528f1d5838ae1cac015024c4e8731484f888d1bsalomon                                                             0));
346410528f1d5838ae1cac015024c4e8731484f888d1bsalomon    }
3465eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com}
3466eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com
34671cbdcde9116e9efb514236faf8cfa42649a041d1joshualittbool GrGLGpu::onCopySurface(GrSurface* dst,
34681cbdcde9116e9efb514236faf8cfa42649a041d1joshualitt                            GrSurface* src,
34691cbdcde9116e9efb514236faf8cfa42649a041d1joshualitt                            const SkIRect& srcRect,
34701cbdcde9116e9efb514236faf8cfa42649a041d1joshualitt                            const SkIPoint& dstPoint) {
34717f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
34727f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    // swizzle.
34731edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    if (this->caps()->shaderCaps()->configOutputSwizzle(src->config()) !=
34741edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        this->caps()->shaderCaps()->configOutputSwizzle(dst->config())) {
34757f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        return false;
34767f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    }
3477083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    // Don't prefer copying as a draw if the dst doesn't already have a FBO object.
3478083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    bool preferCopy = SkToBool(dst->asRenderTarget());
3479083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    if (preferCopy && src->asTexture()) {
3480e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
3481e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            return true;
3482e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        }
348363150afcc0c4120370db6f5566cd404584345668commit-bot@chromium.org    }
34846121405df5689875c7309c20632a82897fce4127cblume
34850f5f967f6777612353c762e6d0095f733adfb326egdaniel    if (can_copy_texsubimage(dst, src, this)) {
34866df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
3487eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com        return true;
3488eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    }
34896df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
3490e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    if (can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this)) {
34916df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
34925df6fee929823f50c55cc50f7c882a309c1b1de9bsalomon    }
34936df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
3494083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    if (!preferCopy && src->asTexture()) {
3495e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
3496e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            return true;
3497e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        }
3498083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    }
3499083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon
3500404b3b264b833eb7cffdc833c7e2ebbd708e123amtklein    return false;
35015df6fee929823f50c55cc50f7c882a309c1b1de9bsalomon}
35025df6fee929823f50c55cc50f7c882a309c1b1de9bsalomon
3503bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomonbool GrGLGpu::createCopyProgram(GrTexture* srcTex) {
3504bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    int progIdx = TextureToCopyProgramIdx(srcTex);
35051edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
3506bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    GrSLType samplerType = srcTex->texturePriv().samplerType();
3507e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3508e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (!fCopyProgramArrayBuffer) {
3509e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        static const GrGLfloat vdata[] = {
3510e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            0, 0,
3511e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            0, 1,
3512e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            1, 0,
3513e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            1, 1
3514e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        };
3515e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fCopyProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType,
3516e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                                                         kStatic_GrAccessPattern, vdata));
3517e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3518e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (!fCopyProgramArrayBuffer) {
3519e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        return false;
3520e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3521e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3522e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    SkASSERT(!fCopyPrograms[progIdx].fProgram);
3523e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL_RET(fCopyPrograms[progIdx].fProgram, CreateProgram());
3524e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (!fCopyPrograms[progIdx].fProgram) {
3525e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        return false;
3526e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3527e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
35281edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    const char* version = shaderCaps->versionDeclString();
352999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
353099938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
353199938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon                               GrShaderVar::kUniform_TypeModifier);
353299938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
353399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar uTexture("u_texture", samplerType, GrShaderVar::kUniform_TypeModifier);
353499938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier);
353599938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
3536deacc97bc63513b5eacaf21f858727f6e8b98ce5cdalton
3537e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    SkString vshaderTxt(version);
35381edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    if (shaderCaps->noperspectiveInterpolationSupport()) {
35391edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3540e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            vshaderTxt.appendf("#extension %s : require\n", extension);
35417ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        }
3542e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        vTexCoord.addModifier("noperspective");
3543e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3544e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
35451edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    aVertex.appendDecl(shaderCaps, &vshaderTxt);
3546e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    vshaderTxt.append(";");
35471edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
3548e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    vshaderTxt.append(";");
35491edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    uPosXform.appendDecl(shaderCaps, &vshaderTxt);
3550e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    vshaderTxt.append(";");
35511edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    vTexCoord.appendDecl(shaderCaps, &vshaderTxt);
3552e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    vshaderTxt.append(";");
3553e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3554e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    vshaderTxt.append(
3555e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "// Copy Program VS\n"
3556e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "void main() {"
3557e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "  v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
3558e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "  gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
3559e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "  gl_Position.zw = vec2(0, 1);"
3560e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "}"
3561e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    );
3562e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3563e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    SkString fshaderTxt(version);
35641edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    if (shaderCaps->noperspectiveInterpolationSupport()) {
35651edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3566e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            fshaderTxt.appendf("#extension %s : require\n", extension);
3567044d3c185876f9960f07b88f068cf08d78311e33mtklein        }
3568e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3569bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    if (samplerType == kTextureExternalSampler_GrSLType) {
3570e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fshaderTxt.appendf("#extension %s : require\n",
35711edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon                           shaderCaps->externalTextureExtensionString());
3572e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
35731edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps,
3574e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                                                 &fshaderTxt);
3575f31ae495271e0343f568fb9a1d7e2df81e196896Brian Salomon    vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier);
35761edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    vTexCoord.appendDecl(shaderCaps, &fshaderTxt);
3577e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fshaderTxt.append(";");
35781edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    uTexture.appendDecl(shaderCaps, &fshaderTxt);
3579e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fshaderTxt.append(";");
3580e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fshaderTxt.appendf(
3581e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "// Copy Program FS\n"
3582e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        "void main() {"
35832b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas        "  sk_FragColor = texture(u_texture, v_texCoord);"
35842b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas        "}"
3585e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    );
3586e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3587e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    const char* str;
3588e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GrGLint length;
3589e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3590e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    str = vshaderTxt.c_str();
3591e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    length = SkToInt(vshaderTxt.size());
3592941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkSL::Program::Settings settings;
3593941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    settings.fCaps = shaderCaps;
3594941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkSL::Program::Inputs inputs;
3595e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
3596e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                                                  GR_GL_VERTEX_SHADER, &str, &length, 1,
3597941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas                                                  &fStats, settings, &inputs);
3598941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkASSERT(inputs.isEmpty());
3599e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3600e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    str = fshaderTxt.c_str();
3601e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    length = SkToInt(fshaderTxt.size());
3602e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
3603e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                                                  GR_GL_FRAGMENT_SHADER, &str, &length, 1,
3604941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas                                                  &fStats, settings, &inputs);
3605941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkASSERT(inputs.isEmpty());
3606e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3607e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL(LinkProgram(fCopyPrograms[progIdx].fProgram));
3608e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3609e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL_RET(fCopyPrograms[progIdx].fTextureUniform,
3610e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texture"));
3611e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL_RET(fCopyPrograms[progIdx].fPosXformUniform,
3612e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_posXform"));
3613e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL_RET(fCopyPrograms[progIdx].fTexCoordXformUniform,
3614e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordXform"));
3615e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3616e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex"));
3617e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3618e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL(DeleteShader(vshader));
3619e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL(DeleteShader(fshader));
3620e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3621e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    return true;
3622044d3c185876f9960f07b88f068cf08d78311e33mtklein}
3623deacc97bc63513b5eacaf21f858727f6e8b98ce5cdalton
362433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosmanbool GrGLGpu::createMipmapProgram(int progIdx) {
362533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    const bool oddWidth = SkToBool(progIdx & 0x2);
362633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    const bool oddHeight = SkToBool(progIdx & 0x1);
362733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    const int numTaps = (oddWidth ? 2 : 1) * (oddHeight ? 2 : 1);
362833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
36291edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
363033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
363133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    SkASSERT(!fMipmapPrograms[progIdx].fProgram);
363233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL_RET(fMipmapPrograms[progIdx].fProgram, CreateProgram());
363333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (!fMipmapPrograms[progIdx].fProgram) {
363433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return false;
363533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
363633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
36371edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    const char* version = shaderCaps->versionDeclString();
363899938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
363999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
364099938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon                               GrShaderVar::kUniform_TypeModifier);
364199938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar uTexture("u_texture", kTexture2DSampler_GrSLType,
364299938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon                         GrShaderVar::kUniform_TypeModifier);
364333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // We need 1, 2, or 4 texture coordinates (depending on parity of each dimension):
364499938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar vTexCoords[] = {
364599938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon        GrShaderVar("v_texCoord0", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
364699938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon        GrShaderVar("v_texCoord1", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
364799938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon        GrShaderVar("v_texCoord2", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
364899938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon        GrShaderVar("v_texCoord3", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
364933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    };
365099938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType,GrShaderVar::kOut_TypeModifier);
365133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
365233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    SkString vshaderTxt(version);
36531edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    if (shaderCaps->noperspectiveInterpolationSupport()) {
36541edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
365533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            vshaderTxt.appendf("#extension %s : require\n", extension);
365633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
365733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vTexCoords[0].addModifier("noperspective");
365833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vTexCoords[1].addModifier("noperspective");
365933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vTexCoords[2].addModifier("noperspective");
366033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vTexCoords[3].addModifier("noperspective");
366133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
366233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
36631edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    aVertex.appendDecl(shaderCaps, &vshaderTxt);
366433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    vshaderTxt.append(";");
36651edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
366633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    vshaderTxt.append(";");
366733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    for (int i = 0; i < numTaps; ++i) {
36681edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        vTexCoords[i].appendDecl(shaderCaps, &vshaderTxt);
366933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vshaderTxt.append(";");
367033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
367133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
367233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    vshaderTxt.append(
367333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        "// Mipmap Program VS\n"
367433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        "void main() {"
367533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        "  gl_Position.xy = a_vertex * vec2(2, 2) - vec2(1, 1);"
367633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        "  gl_Position.zw = vec2(0, 1);"
367733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    );
367833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
367933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Insert texture coordinate computation:
368033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (oddWidth && oddHeight) {
368133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vshaderTxt.append(
368233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord0 = a_vertex.xy * u_texCoordXform.yw;"
368333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord1 = a_vertex.xy * u_texCoordXform.yw + vec2(u_texCoordXform.x, 0);"
368433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord2 = a_vertex.xy * u_texCoordXform.yw + vec2(0, u_texCoordXform.z);"
368533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord3 = a_vertex.xy * u_texCoordXform.yw + u_texCoordXform.xz;"
368633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        );
368733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    } else if (oddWidth) {
368833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vshaderTxt.append(
368933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord0 = a_vertex.xy * vec2(u_texCoordXform.y, 1);"
369033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord1 = a_vertex.xy * vec2(u_texCoordXform.y, 1) + vec2(u_texCoordXform.x, 0);"
369133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        );
369233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    } else if (oddHeight) {
369333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vshaderTxt.append(
369433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord0 = a_vertex.xy * vec2(1, u_texCoordXform.w);"
369533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord1 = a_vertex.xy * vec2(1, u_texCoordXform.w) + vec2(0, u_texCoordXform.z);"
369633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        );
369733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    } else {
369833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        vshaderTxt.append(
369933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            "  v_texCoord0 = a_vertex.xy;"
370033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        );
370133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
370233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
370333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    vshaderTxt.append("}");
370433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
370533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    SkString fshaderTxt(version);
37061edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    if (shaderCaps->noperspectiveInterpolationSupport()) {
37071edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
370833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            fshaderTxt.appendf("#extension %s : require\n", extension);
370933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
371033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
37111edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps,
371233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                                 &fshaderTxt);
371333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    for (int i = 0; i < numTaps; ++i) {
3714f31ae495271e0343f568fb9a1d7e2df81e196896Brian Salomon        vTexCoords[i].setTypeModifier(GrShaderVar::kIn_TypeModifier);
37151edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon        vTexCoords[i].appendDecl(shaderCaps, &fshaderTxt);
371633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        fshaderTxt.append(";");
371733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
37181edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    uTexture.appendDecl(shaderCaps, &fshaderTxt);
371933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    fshaderTxt.append(";");
372033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    fshaderTxt.append(
372133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        "// Mipmap Program FS\n"
372233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        "void main() {"
372333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    );
372433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
372533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (oddWidth && oddHeight) {
37262b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas        fshaderTxt.append(
37272b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas            "  sk_FragColor = (texture(u_texture, v_texCoord0) + "
37282b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas            "                  texture(u_texture, v_texCoord1) + "
37292b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas            "                  texture(u_texture, v_texCoord2) + "
37302b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas            "                  texture(u_texture, v_texCoord3)) * 0.25;"
373133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        );
373233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    } else if (oddWidth || oddHeight) {
37332b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas        fshaderTxt.append(
37342b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas            "  sk_FragColor = (texture(u_texture, v_texCoord0) + "
37352b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas            "                  texture(u_texture, v_texCoord1)) * 0.5;"
373633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        );
373733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    } else {
37382b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas        fshaderTxt.append(
37392b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas            "  sk_FragColor = texture(u_texture, v_texCoord0);"
374033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        );
374133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
374233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
374333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    fshaderTxt.append("}");
374433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
374533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    const char* str;
374633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrGLint length;
374733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
374833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    str = vshaderTxt.c_str();
374933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    length = SkToInt(vshaderTxt.size());
3750941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkSL::Program::Settings settings;
3751941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    settings.fCaps = shaderCaps;
3752941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkSL::Program::Inputs inputs;
375333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
375433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                                  GR_GL_VERTEX_SHADER, &str, &length, 1,
3755941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas                                                  &fStats, settings, &inputs);
3756941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkASSERT(inputs.isEmpty());
375733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
375833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    str = fshaderTxt.c_str();
375933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    length = SkToInt(fshaderTxt.size());
376033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
376133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                                  GR_GL_FRAGMENT_SHADER, &str, &length, 1,
3762941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas                                                  &fStats, settings, &inputs);
3763941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkASSERT(inputs.isEmpty());
376433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
376533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL(LinkProgram(fMipmapPrograms[progIdx].fProgram));
376633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
376733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL_RET(fMipmapPrograms[progIdx].fTextureUniform,
376833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texture"));
376933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL_RET(fMipmapPrograms[progIdx].fTexCoordXformUniform,
377033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texCoordXform"));
377133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
377233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL(BindAttribLocation(fMipmapPrograms[progIdx].fProgram, 0, "a_vertex"));
377333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
377433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL(DeleteShader(vshader));
377533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL(DeleteShader(fshader));
377633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
377733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    return true;
377833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman}
377933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
3780e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonbool GrGLGpu::createWireRectProgram() {
3781e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (!fWireRectArrayBuffer) {
3782e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        static const GrGLfloat vdata[] = {
3783e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            0, 0,
3784e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            0, 1,
3785e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            1, 1,
3786e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            1, 0
3787e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        };
3788e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        fWireRectArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType,
3789e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton                                                      kStatic_GrAccessPattern, vdata));
3790e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        if (!fWireRectArrayBuffer) {
3791e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            return false;
3792e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        }
3793e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3794e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
37956dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    SkASSERT(!fWireRectProgram.fProgram);
3796e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GL_CALL_RET(fWireRectProgram.fProgram, CreateProgram());
3797e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (!fWireRectProgram.fProgram) {
3798e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        return false;
3799e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3800e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
380199938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar uColor("u_color", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
380299938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar uRect("u_rect", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
380399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
38041edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    const char* version = this->caps()->shaderCaps()->versionDeclString();
38056dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38066dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    // The rect uniform specifies the rectangle in NDC space as a vec4 (left,top,right,bottom). The
38076dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    // program is used with a vbo containing the unit square. Vertices are computed from the rect
38086dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    // uniform using the 4 vbo vertices.
38096dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    SkString vshaderTxt(version);
38101edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    aVertex.appendDecl(this->caps()->shaderCaps(), &vshaderTxt);
38116dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    vshaderTxt.append(";");
38121edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    uRect.appendDecl(this->caps()->shaderCaps(), &vshaderTxt);
38136dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    vshaderTxt.append(";");
38146dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    vshaderTxt.append(
38156dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "// Wire Rect Program VS\n"
38166dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "void main() {"
38176dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "  gl_Position.x = u_rect.x + a_vertex.x * (u_rect.z - u_rect.x);"
38186dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "  gl_Position.y = u_rect.y + a_vertex.y * (u_rect.w - u_rect.y);"
38196dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "  gl_Position.zw = vec2(0, 1);"
38206dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "}"
38216dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    );
38226dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
382399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon    GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
38246dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38256dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    SkString fshaderTxt(version);
38266dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
38271edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon                                                 *this->caps()->shaderCaps(),
38286dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon                                                 &fshaderTxt);
38291edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    uColor.appendDecl(this->caps()->shaderCaps(), &fshaderTxt);
38306dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    fshaderTxt.append(";");
38316dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    fshaderTxt.appendf(
38326dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "// Write Rect Program FS\n"
38336dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "void main() {"
38345961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas        "  sk_FragColor = %s;"
38356dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        "}",
38366dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        uColor.c_str()
38376dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    );
38386dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38396dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    const char* str;
38406dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrGLint length;
38416dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38426dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    str = vshaderTxt.c_str();
38436dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    length = SkToInt(vshaderTxt.size());
3844941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkSL::Program::Settings settings;
3845941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    settings.fCaps = this->caps()->shaderCaps();
3846941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkSL::Program::Inputs inputs;
38476dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram,
38486dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon                                                  GR_GL_VERTEX_SHADER, &str, &length, 1,
3849941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas                                                  &fStats, settings, &inputs);
3850941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkASSERT(inputs.isEmpty());
38516dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38526dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    str = fshaderTxt.c_str();
38536dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    length = SkToInt(fshaderTxt.size());
38546dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram,
38556dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon                                                  GR_GL_FRAGMENT_SHADER, &str, &length, 1,
3856941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas                                                  &fStats, settings, &inputs);
3857941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas    SkASSERT(inputs.isEmpty());
38586dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38596dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(LinkProgram(fWireRectProgram.fProgram));
38606dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38616dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL_RET(fWireRectProgram.fColorUniform,
38626dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon                GetUniformLocation(fWireRectProgram.fProgram, "u_color"));
38636dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL_RET(fWireRectProgram.fRectUniform,
38646dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon                GetUniformLocation(fWireRectProgram.fProgram, "u_rect"));
38656dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(BindAttribLocation(fWireRectProgram.fProgram, 0, "a_vertex"));
38666dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38676dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(DeleteShader(vshader));
38686dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(DeleteShader(fshader));
3869e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3870e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    return true;
38716dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon}
38726dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38736dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomonvoid GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) {
38747f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    // TODO: This should swizzle the output to match dst's config, though it is a debugging
38757f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    // visualization.
38767f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon
38776dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    this->handleDirtyContext();
38786dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    if (!fWireRectProgram.fProgram) {
3879e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        if (!this->createWireRectProgram()) {
3880e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            SkDebugf("Failed to create wire rect program.\n");
3881e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            return;
3882e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        }
38836dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    }
38846dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38856dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    int w = rt->width();
38866dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    int h = rt->height();
38876dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
38886dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    // Compute the edges of the rectangle (top,left,right,bottom) in NDC space. Must consider
38896dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    // whether the render target is flipped or not.
38906dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrGLfloat edges[4];
38916dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    edges[0] = SkIntToScalar(rect.fLeft) + 0.5f;
38926dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    edges[2] = SkIntToScalar(rect.fRight) - 0.5f;
38936dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
38946dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        edges[1] = h - (SkIntToScalar(rect.fTop) + 0.5f);
38956dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        edges[3] = h - (SkIntToScalar(rect.fBottom) - 0.5f);
38966dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    } else {
38976dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        edges[1] = SkIntToScalar(rect.fTop) + 0.5f;
38986dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon        edges[3] = SkIntToScalar(rect.fBottom) - 0.5f;
38996dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    }
39006dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    edges[0] = 2 * edges[0] / w - 1.0f;
39016dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    edges[1] = 2 * edges[1] / h - 1.0f;
39026dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    edges[2] = 2 * edges[2] / w - 1.0f;
39036dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    edges[3] = 2 * edges[3] / h - 1.0f;
39046dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
39056dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrGLfloat channels[4];
39066dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    static const GrGLfloat scale255 = 1.f / 255.f;
39076dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    channels[0] = GrColorUnpackR(color) * scale255;
39086dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    channels[1] = GrColorUnpackG(color) * scale255;
39096dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    channels[2] = GrColorUnpackB(color) * scale255;
39106dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    channels[3] = GrColorUnpackA(color) * scale255;
39116dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
39126dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget());
39136dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    this->flushRenderTarget(glRT, &rect);
39146dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
39156dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(UseProgram(fWireRectProgram.fProgram));
39166dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    fHWProgramID = fWireRectProgram.fProgram;
39176dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
3918e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fHWVertexArrayState.setVertexArrayID(this, 0);
39196dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
3920e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
3921144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    attribs->set(this, 0, fWireRectArrayBuffer.get(), kVec2f_GrVertexAttribType,
3922144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary                 2 * sizeof(GrGLfloat), 0);
39236dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    attribs->disableUnusedArrays(this, 0x1);
39246dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
39256dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(Uniform4fv(fWireRectProgram.fRectUniform, 1, edges));
39266dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(Uniform4fv(fWireRectProgram.fColorUniform, 1, channels));
39276dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
39286dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GrXferProcessor::BlendInfo blendInfo;
39296dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    blendInfo.reset();
39307f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    this->flushBlend(blendInfo, GrSwizzle::RGBA());
39316dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    this->flushColorWrite(true);
39325fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips    this->flushDrawFace(GrDrawFace::kBoth);
3933af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton    this->flushHWAAState(glRT, false, false);
39346dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    this->disableScissor();
393528341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    this->disableWindowRectangles();
3936c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton    this->disableStencil();
39376dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
39386dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon    GL_CALL(DrawArrays(GR_GL_LINE_LOOP, 0, 4));
39396dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon}
39406dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
39416dea83f244cfdea52901eef6b31cee60b07a8ea0bsalomon
3942e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonbool GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
39436df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                GrSurface* src,
39446df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                const SkIRect& srcRect,
39456df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                const SkIPoint& dstPoint) {
3946e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
3947bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    int progIdx = TextureToCopyProgramIdx(srcTex);
3948e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
3949e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (!fCopyPrograms[progIdx].fProgram) {
3950bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        if (!this->createCopyProgram(srcTex)) {
3951e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            SkDebugf("Failed to create copy program.\n");
3952e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            return false;
3953e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        }
3954e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    }
3955e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton
39566df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    int w = srcRect.width();
39576df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    int h = srcRect.height();
39586df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
3959514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
3960a6359365887048ef055196de75591311d7a015f0brianosman    this->bindTexture(0, params, true, srcTex);
39616df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
3962083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    GrGLIRect dstVP;
396371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
3964083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    this->flushViewport(dstVP);
3965294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    fHWBoundRenderTargetUniqueID.makeInvalid();
3966083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon
39676df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
39686df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
39697ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram));
39707ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    fHWProgramID = fCopyPrograms[progIdx].fProgram;
39716df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
3972e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    fHWVertexArrayState.setVertexArrayID(this, 0);
39736df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
3974e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
3975144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kVec2f_GrVertexAttribType,
3976144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary                 2 * sizeof(GrGLfloat), 0);
3977d624634aff330485dc56fc09773cc6d4ec092c4dbsalomon    attribs->disableUnusedArrays(this, 0x1);
39786df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
39796df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    // dst rect edges in NDC (-1 to 1)
39806df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    int dw = dst->width();
39816df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    int dh = dst->height();
39826df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f;
39836df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
39846df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f;
39856df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
39866df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
39876df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        dy0 = -dy0;
39886df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        dy1 = -dy1;
39896df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    }
39906df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
3991e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft;
3992e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w);
3993e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    GrGLfloat sy0 = (GrGLfloat)srcRect.fTop;
3994e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h);
39956df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    int sh = src->height();
39966df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
3997e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        sy0 = sh - sy0;
3998e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        sy1 = sh - sy1;
3999e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    }
4000e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    // src rect edges in normalized texture space (0 to 1) unless we're using a RECTANGLE texture.
4001e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    GrGLenum srcTarget = srcTex->target();
4002e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon    if (GR_GL_TEXTURE_RECTANGLE != srcTarget) {
4003e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        int sw = src->width();
4004e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        sx0 /= sw;
4005e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        sx1 /= sw;
4006e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        sy0 /= sh;
4007e5286e0b37abe4d0db67a6b3d87b2d5a12a70ab3bsalomon        sy1 /= sh;
40086df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    }
40096df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
40107ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
40117ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,
40127ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon                      sx1 - sx0, sy1 - sy0, sx0, sy0));
40137ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0));
40146df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
40156df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrXferProcessor::BlendInfo blendInfo;
40166df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    blendInfo.reset();
40177f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    this->flushBlend(blendInfo, GrSwizzle::RGBA());
40186df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    this->flushColorWrite(true);
40195fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips    this->flushDrawFace(GrDrawFace::kBoth);
4020083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    this->flushHWAAState(nullptr, false, false);
40216df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    this->disableScissor();
402228341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    this->disableWindowRectangles();
4023c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton    this->disableStencil();
40246df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
40256df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
402671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst);
4027083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    this->didWriteToSurface(dst, &dstRect);
4028083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon
4029e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    return true;
40306df86409ca586c3cb34f616f03501bd96181f9e4bsalomon}
40316df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
40326df86409ca586c3cb34f616f03501bd96181f9e4bsalomonvoid GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst,
40336df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                           GrSurface* src,
40346df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                           const SkIRect& srcRect,
40356df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                           const SkIPoint& dstPoint) {
40366df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    SkASSERT(can_copy_texsubimage(dst, src, this));
40376df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLIRect srcVP;
403871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
4039083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture());
40406df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    SkASSERT(dstTex);
40416df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    // We modified the bound FBO
4042294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    fHWBoundRenderTargetUniqueID.makeInvalid();
40436df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLIRect srcGLRect;
40446df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    srcGLRect.setRelativeTo(srcVP,
40456df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.fLeft,
40466df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.fTop,
40476df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.width(),
40486df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.height(),
40496df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            src->origin());
40506df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
40516df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    this->setScratchTextureUnit();
405210528f1d5838ae1cac015024c4e8731484f888d1bsalomon    GL_CALL(BindTexture(dstTex->target(), dstTex->textureID()));
40536df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLint dstY;
40546df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
40556df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
40566df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    } else {
40576df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        dstY = dstPoint.fY;
40586df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    }
405910528f1d5838ae1cac015024c4e8731484f888d1bsalomon    GL_CALL(CopyTexSubImage2D(dstTex->target(), 0,
4060083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon                              dstPoint.fX, dstY,
4061083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon                              srcGLRect.fLeft, srcGLRect.fBottom,
4062083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon                              srcGLRect.fWidth, srcGLRect.fHeight));
406371d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, src);
4064083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
4065083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon                                        srcRect.width(), srcRect.height());
4066083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    this->didWriteToSurface(dst, &dstRect);
40676df86409ca586c3cb34f616f03501bd96181f9e4bsalomon}
40686df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
40696df86409ca586c3cb34f616f03501bd96181f9e4bsalomonbool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst,
40706df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                           GrSurface* src,
40716df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                           const SkIRect& srcRect,
40726df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                           const SkIPoint& dstPoint) {
4073e5e7eb1478b6a856480c03ac986c4e6bb32d9f80Brian Salomon    SkASSERT(can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this));
40746df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
40756df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                                        srcRect.width(), srcRect.height());
40766df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    if (dst == src) {
40776df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) {
40786df86409ca586c3cb34f616f03501bd96181f9e4bsalomon            return false;
40796df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        }
40806df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    }
40816df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
40826df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLIRect dstVP;
40836df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLIRect srcVP;
408471d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->bindSurfaceFBOForPixelOps(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
408571d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->bindSurfaceFBOForPixelOps(src, GR_GL_READ_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
40866df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    // We modified the bound FBO
4087294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    fHWBoundRenderTargetUniqueID.makeInvalid();
40886df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLIRect srcGLRect;
40896df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLIRect dstGLRect;
40906df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    srcGLRect.setRelativeTo(srcVP,
40916df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.fLeft,
40926df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.fTop,
40936df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.width(),
40946df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcRect.height(),
40956df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            src->origin());
40966df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    dstGLRect.setRelativeTo(dstVP,
40976df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstRect.fLeft,
40986df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstRect.fTop,
40996df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstRect.width(),
41006df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstRect.height(),
41016df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dst->origin());
41026df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
41036df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    // BlitFrameBuffer respects the scissor, so disable it.
41046df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    this->disableScissor();
410528341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    this->disableWindowRectangles();
41066df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
41076df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLint srcY0;
41086df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GrGLint srcY1;
41096df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    // Does the blit need to y-mirror or not?
41106df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    if (src->origin() == dst->origin()) {
41116df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        srcY0 = srcGLRect.fBottom;
41126df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        srcY1 = srcGLRect.fBottom + srcGLRect.fHeight;
41136df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    } else {
41146df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        srcY0 = srcGLRect.fBottom + srcGLRect.fHeight;
41156df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        srcY1 = srcGLRect.fBottom;
41166df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    }
41176df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    GL_CALL(BlitFramebuffer(srcGLRect.fLeft,
41186df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcY0,
41196df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcGLRect.fLeft + srcGLRect.fWidth,
41206df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            srcY1,
41216df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstGLRect.fLeft,
41226df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstGLRect.fBottom,
41236df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstGLRect.fLeft + dstGLRect.fWidth,
41246df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            dstGLRect.fBottom + dstGLRect.fHeight,
41256df86409ca586c3cb34f616f03501bd96181f9e4bsalomon                            GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
412671d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->unbindTextureFBOForPixelOps(GR_GL_DRAW_FRAMEBUFFER, dst);
412771d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    this->unbindTextureFBOForPixelOps(GR_GL_READ_FRAMEBUFFER, src);
4128083617b9a7247dd4c52f8dfd195fa34a083e6f1dbsalomon    this->didWriteToSurface(dst, &dstRect);
41296df86409ca586c3cb34f616f03501bd96181f9e4bsalomon    return true;
41306df86409ca586c3cb34f616f03501bd96181f9e4bsalomon}
41316df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
413233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman// Manual implementation of mipmap generation, to work around driver bugs w/sRGB.
413333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman// Uses draw calls to do a series of downsample operations to successive mips.
413433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman// If this returns false, then the calling code falls back to using glGenerateMipmap.
413533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosmanbool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) {
4136bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    SkASSERT(!GrPixelConfigIsSint(texture->config()));
413709563cec928da5052972b3dca7f022fca3a72d05brianosman    // Our iterative downsample requires the ability to limit which level we're sampling:
413809563cec928da5052972b3dca7f022fca3a72d05brianosman    if (!this->glCaps().doManualMipmapping()) {
413933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return false;
414033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
414133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
414233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Mipmaps are only supported on 2D textures:
414333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (GR_GL_TEXTURE_2D != texture->target()) {
414433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return false;
414533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
414633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
414733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // We need to be able to render to the texture for this to work:
414871d9d84d6cd38b9dc8711849952bb9e668ab33a2Brian Salomon    if (!this->glCaps().canConfigBeFBOColorAttachment(texture->config())) {
414933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return false;
415033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
415133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
415233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // If we're mipping an sRGB texture, we need to ensure FB sRGB is correct:
415333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (GrPixelConfigIsSRGB(texture->config())) {
415433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        // If we have write-control, just set the state that we want:
415533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        if (this->glCaps().srgbWriteControl()) {
415633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            this->flushFramebufferSRGB(gammaCorrect);
415733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        } else if (!gammaCorrect) {
415833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            // If we don't have write-control we can't do non-gamma-correct mipmapping:
415933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            return false;
416033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
416133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
416233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
416333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    int width = texture->width();
416433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    int height = texture->height();
416533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1;
416633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
416733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Define all mips, if we haven't previously done so:
416833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (0 == texture->texturePriv().maxMipMapLevel()) {
416933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GrGLenum internalFormat;
417033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GrGLenum externalFormat;
417133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GrGLenum externalType;
417233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        if (!this->glCaps().getTexImageFormats(texture->config(), texture->config(),
417333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                               &internalFormat, &externalFormat, &externalType)) {
417433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            return false;
417533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
417633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
417733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        for (GrGLint level = 1; level < levelCount; ++level) {
417833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            // Define the next mip:
417933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            width = SkTMax(1, width / 2);
418033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            height = SkTMax(1, height / 2);
418133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, level, internalFormat,
418233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                                          width, height, 0,
418333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                                          externalFormat, externalType, nullptr));
418433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
418533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
418633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
418733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Create (if necessary), then bind temporary FBO:
418833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (0 == fTempDstFBOID) {
418933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(GenFramebuffers(1, &fTempDstFBOID));
419033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
419133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID));
4192294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    fHWBoundRenderTargetUniqueID.makeInvalid();
419333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
419433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Bind the texture, to get things configured for filtering.
419533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // We'll be changing our base level further below:
419633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    this->setTextureUnit(0);
4197514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kBilerp_FilterMode);
419833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    this->bindTexture(0, params, gammaCorrect, texture);
419933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
420033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Vertex data:
420133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (!fMipmapProgramArrayBuffer) {
420233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        static const GrGLfloat vdata[] = {
420333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            0, 0,
420433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            0, 1,
420533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            1, 0,
420633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            1, 1
420733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        };
420833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        fMipmapProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata),
420933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                                           kVertex_GrBufferType,
421033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                                           kStatic_GrAccessPattern, vdata));
421133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
421233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    if (!fMipmapProgramArrayBuffer) {
421333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        return false;
421433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
421533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
421633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    fHWVertexArrayState.setVertexArrayID(this, 0);
421733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
421833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
4219144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    attribs->set(this, 0, fMipmapProgramArrayBuffer.get(), kVec2f_GrVertexAttribType,
422033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                 2 * sizeof(GrGLfloat), 0);
422133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    attribs->disableUnusedArrays(this, 0x1);
422233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
422333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Set "simple" state once:
422433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrXferProcessor::BlendInfo blendInfo;
422533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    blendInfo.reset();
422633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    this->flushBlend(blendInfo, GrSwizzle::RGBA());
422733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    this->flushColorWrite(true);
42285fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips    this->flushDrawFace(GrDrawFace::kBoth);
422933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    this->flushHWAAState(nullptr, false, false);
423033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    this->disableScissor();
423128341fad8438b294ed7311edbc68d8cb34a990abcsmartdalton    this->disableWindowRectangles();
4232c7d853343a42e28edd9c38a3308afaa846fce1bccsmartdalton    this->disableStencil();
423333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
423433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Do all the blits:
423533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    width = texture->width();
423633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    height = texture->height();
423733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GrGLIRect viewport;
423833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    viewport.fLeft = 0;
423933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    viewport.fBottom = 0;
424033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    for (GrGLint level = 1; level < levelCount; ++level) {
424133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        // Get and bind the program for this particular downsample (filter shape can vary):
424233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        int progIdx = TextureSizeToMipmapProgramIdx(width, height);
424333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        if (!fMipmapPrograms[progIdx].fProgram) {
424433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            if (!this->createMipmapProgram(progIdx)) {
424533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                SkDebugf("Failed to create mipmap program.\n");
424633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                return false;
424733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman            }
424833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        }
424933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(UseProgram(fMipmapPrograms[progIdx].fProgram));
425033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        fHWProgramID = fMipmapPrograms[progIdx].fProgram;
425133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
425233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        // Texcoord uniform is expected to contain (1/w, (w-1)/w, 1/h, (h-1)/h)
425333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        const float invWidth = 1.0f / width;
425433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        const float invHeight = 1.0f / height;
425533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(Uniform4f(fMipmapPrograms[progIdx].fTexCoordXformUniform,
425633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                          invWidth, (width - 1) * invWidth, invHeight, (height - 1) * invHeight));
425733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(Uniform1i(fMipmapPrograms[progIdx].fTextureUniform, 0));
425833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
425933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        // Only sample from previous mip
426033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level - 1));
426133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
426233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
426333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                     GR_GL_TEXTURE_2D, texture->textureID(), level));
426433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
426533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        width = SkTMax(1, width / 2);
426633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        height = SkTMax(1, height / 2);
426733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        viewport.fWidth = width;
426833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        viewport.fHeight = height;
426933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        this->flushViewport(viewport);
427033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
427133f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman        GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
427233f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    }
427333f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
427433f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    // Unbind:
427533f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
427633f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman                                 GR_GL_TEXTURE_2D, 0, 0));
427733f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
427833f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman    return true;
427933f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman}
428033f6b3f6ee4de24282f5e7f2dc31a5f538bcf40cbrianosman
4281c25c5d73e9f4d840dc758c399496d5690709ad58csmartdaltonvoid GrGLGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings& stencil,
4282c25c5d73e9f4d840dc758c399496d5690709ad58csmartdalton                                      int* effectiveSampleCnt, SamplePattern* samplePattern) {
4283f9635999a4aa8810d04e8ef04594a9fbcc061e3dcsmartdalton    SkASSERT(!rt->isMixedSampled() || rt->renderTargetPriv().getStencilAttachment() ||
428428f45b949acc746849100fbe112ee5280f0594c9cdalton             stencil.isDisabled());
428528f45b949acc746849100fbe112ee5280f0594c9cdalton
428628f45b949acc746849100fbe112ee5280f0594c9cdalton    this->flushStencil(stencil);
428728f45b949acc746849100fbe112ee5280f0594c9cdalton    this->flushHWAAState(rt, true, !stencil.isDisabled());
428828f45b949acc746849100fbe112ee5280f0594c9cdalton    this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyIRect());
428928f45b949acc746849100fbe112ee5280f0594c9cdalton
429028f45b949acc746849100fbe112ee5280f0594c9cdalton    if (0 != this->caps()->maxRasterSamples()) {
429128f45b949acc746849100fbe112ee5280f0594c9cdalton        GR_GL_GetIntegerv(this->glInterface(), GR_GL_EFFECTIVE_RASTER_SAMPLES, effectiveSampleCnt);
429228f45b949acc746849100fbe112ee5280f0594c9cdalton    } else {
429328f45b949acc746849100fbe112ee5280f0594c9cdalton        GR_GL_GetIntegerv(this->glInterface(), GR_GL_SAMPLES, effectiveSampleCnt);
429428f45b949acc746849100fbe112ee5280f0594c9cdalton    }
429528f45b949acc746849100fbe112ee5280f0594c9cdalton
429628f45b949acc746849100fbe112ee5280f0594c9cdalton    SkASSERT(*effectiveSampleCnt >= rt->desc().fSampleCnt);
429728f45b949acc746849100fbe112ee5280f0594c9cdalton
429828f45b949acc746849100fbe112ee5280f0594c9cdalton    if (this->caps()->sampleLocationsSupport()) {
42990d28e574ac73fef8bf75cab083ffe23f2d8860a1csmartdalton        samplePattern->reset(*effectiveSampleCnt);
430028f45b949acc746849100fbe112ee5280f0594c9cdalton        for (int i = 0; i < *effectiveSampleCnt; ++i) {
430128f45b949acc746849100fbe112ee5280f0594c9cdalton            GrGLfloat pos[2];
430228f45b949acc746849100fbe112ee5280f0594c9cdalton            GL_CALL(GetMultisamplefv(GR_GL_SAMPLE_POSITION, i, pos));
430328f45b949acc746849100fbe112ee5280f0594c9cdalton            if (kTopLeft_GrSurfaceOrigin == rt->origin()) {
43040d28e574ac73fef8bf75cab083ffe23f2d8860a1csmartdalton                (*samplePattern)[i].set(pos[0], pos[1]);
430528f45b949acc746849100fbe112ee5280f0594c9cdalton            } else {
43060d28e574ac73fef8bf75cab083ffe23f2d8860a1csmartdalton                (*samplePattern)[i].set(pos[0], 1 - pos[1]);
430728f45b949acc746849100fbe112ee5280f0594c9cdalton            }
430828f45b949acc746849100fbe112ee5280f0594c9cdalton        }
430928f45b949acc746849100fbe112ee5280f0594c9cdalton    }
431028f45b949acc746849100fbe112ee5280f0594c9cdalton}
431128f45b949acc746849100fbe112ee5280f0594c9cdalton
4312231c5fd590c898957d65cbfbc51040c7fe236af6cdaltonvoid GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) {
4313cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon    SkASSERT(type);
43149954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton    switch (type) {
4315231c5fd590c898957d65cbfbc51040c7fe236af6cdalton        case kTexture_GrXferBarrierType: {
4316231c5fd590c898957d65cbfbc51040c7fe236af6cdalton            GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt);
4317231c5fd590c898957d65cbfbc51040c7fe236af6cdalton            if (glrt->textureFBOID() != glrt->renderFBOID()) {
4318231c5fd590c898957d65cbfbc51040c7fe236af6cdalton                // The render target uses separate storage so no need for glTextureBarrier.
4319231c5fd590c898957d65cbfbc51040c7fe236af6cdalton                // FIXME: The render target will resolve automatically when its texture is bound,
4320231c5fd590c898957d65cbfbc51040c7fe236af6cdalton                // but we could resolve only the bounds that will be read if we do it here instead.
4321231c5fd590c898957d65cbfbc51040c7fe236af6cdalton                return;
4322231c5fd590c898957d65cbfbc51040c7fe236af6cdalton            }
43239954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton            SkASSERT(this->caps()->textureBarrierSupport());
43249954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton            GL_CALL(TextureBarrier());
43259954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton            return;
4326231c5fd590c898957d65cbfbc51040c7fe236af6cdalton        }
43278917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton        case kBlend_GrXferBarrierType:
43284b91f768b348aa1cebeb54f3ff9331938734c242bsalomon            SkASSERT(GrCaps::kAdvanced_BlendEquationSupport ==
43298917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton                     this->caps()->blendEquationSupport());
43308917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton            GL_CALL(BlendBarrier());
43318917d62ef4d9bde9ec4f879dc42b309b03a0ad98cdalton            return;
4332cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon        default: break; // placate compiler warnings that kNone not handled
43339954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton    }
43349954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton}
43359954bc38c498f6b9e9d8c0bcc5cd00d45bfc6e23cdalton
4336889579287770ba35156a73aa02d9ef5d2313c490jvanverthGrBackendObject GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h,
43370a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel                                                         GrPixelConfig config, bool /*isRT*/) {
4338926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon    if (!this->caps()->isConfigTexturable(config)) {
4339926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon        return false;
4340926cb023892378a2eb7c05fc0bce8650ec09ceb1bsalomon    }
434118b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner    std::unique_ptr<GrGLTextureInfo> info = skstd::make_unique<GrGLTextureInfo>();
4342091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    info->fTarget = GR_GL_TEXTURE_2D;
4343546eb5c57aebee47172f9d2a3eae6b49945dba08kkinnunen    info->fID = 0;
4344091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(GenTextures(1, &info->fID));
4345672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth    GL_CALL(ActiveTexture(GR_GL_TEXTURE0));
4346672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth    GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1));
4347091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(BindTexture(info->fTarget, info->fID));
4348294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    fHWBoundTextureUniqueIDs[0].makeInvalid();
4349091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
4350091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
4351091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
4352091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
4353672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
435476148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum internalFormat;
435576148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum externalFormat;
435676148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    GrGLenum externalType;
435776148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon
435876148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat,
435976148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon                                           &externalType)) {
436076148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon        return reinterpret_cast<GrBackendObject>(nullptr);
436176148af6df1f8da67cbed13b4d8216b36a41b3ddbsalomon    }
4362672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
4363091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GL_CALL(TexImage2D(info->fTarget, 0, internalFormat, w, h, 0, externalFormat,
4364672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth                       externalType, pixels));
4365672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
436618b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner    return reinterpret_cast<GrBackendObject>(info.release());
4367672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth}
4368672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
4369889579287770ba35156a73aa02d9ef5d2313c490jvanverthbool GrGLGpu::isTestingOnlyBackendTexture(GrBackendObject id) const {
4370091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GrGLuint texID = reinterpret_cast<const GrGLTextureInfo*>(id)->fID;
4371672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
4372672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth    GrGLboolean result;
4373672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth    GL_CALL_RET(result, IsTexture(texID));
4374672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
4375672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth    return (GR_GL_TRUE == result);
4376672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth}
4377672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
4378e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomonvoid GrGLGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandonTexture) {
437918b61f9cb9d0bea03dc4f69f63f53ad44f171526Ben Wagner    std::unique_ptr<const GrGLTextureInfo> info(reinterpret_cast<const GrGLTextureInfo*>(id));
4380091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon    GrGLuint texID = info->fID;
4381091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon
438267d7620285cdfa60158add6615db03bd48e6d8b0bsalomon    if (!abandonTexture) {
438367d7620285cdfa60158add6615db03bd48e6d8b0bsalomon        GL_CALL(DeleteTextures(1, &texID));
438467d7620285cdfa60158add6615db03bd48e6d8b0bsalomon    }
4385672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth}
4386672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
43878fd844f38ed46eaac78bb187623ffcc40b592707joshualittvoid GrGLGpu::resetShaderCacheForTesting() const {
43888fd844f38ed46eaac78bb187623ffcc40b592707joshualitt    fProgramCache->abandon();
43898fd844f38ed46eaac78bb187623ffcc40b592707joshualitt}
43908fd844f38ed46eaac78bb187623ffcc40b592707joshualitt
43916918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com///////////////////////////////////////////////////////////////////////////////
43926df86409ca586c3cb34f616f03501bd96181f9e4bsalomon
4393e2e71c2df4e72e897bbe745752be0444aee5c29fcdaltonGrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu,
4394485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton                                                                           const GrBuffer* ibuf) {
43954f65a2750007725349774e53067df3307376257crobertphillips@google.com    GrGLAttribArrayState* attribState;
43964f65a2750007725349774e53067df3307376257crobertphillips@google.com
4397e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton    if (gpu->glCaps().isCoreProfile()) {
4398e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        if (!fCoreProfileVertexArray) {
43996918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            GrGLuint arrayID;
44006918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID));
44016918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            int attrCount = gpu->glCaps().maxVertexAttributes();
4402e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            fCoreProfileVertexArray = new GrGLVertexArray(arrayID, attrCount);
44037acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com        }
4404e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        if (ibuf) {
4405e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            attribState = fCoreProfileVertexArray->bindWithIndexBuffer(gpu, ibuf);
44066df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        } else {
4407e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            attribState = fCoreProfileVertexArray->bind(gpu);
44086df86409ca586c3cb34f616f03501bd96181f9e4bsalomon        }
44096918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    } else {
4410e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton        if (ibuf) {
4411e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            // bindBuffer implicitly binds VAO 0 when binding an index buffer.
4412e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton            gpu->bindBuffer(kIndex_GrBufferType, ibuf);
44136918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        } else {
44146918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            this->setVertexArrayID(gpu, 0);
4415880b8fcf255e67a15687e8b7cc47397372db683cbsalomon@google.com        }
44166918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        int attrCount = gpu->glCaps().maxVertexAttributes();
44176918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        if (fDefaultVertexArrayAttribState.count() != attrCount) {
44186918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            fDefaultVertexArrayAttribState.resize(attrCount);
44197acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com        }
44206918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        attribState = &fDefaultVertexArrayAttribState;
44217acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com    }
44226918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    return attribState;
44237acdb8e1d29fe50454431d768ddc862b693db8b0bsalomon@google.com}
4424e179a9167f71dfc41668b05d40082aae76367fa6bsalomon
44253798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillipsbool GrGLGpu::onIsACopyNeededForTextureParams(GrTextureProxy* proxy,
442681444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips                                              const GrSamplerParams& textureParams,
442781444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips                                              GrTextureProducer::CopyParams* copyParams,
442881444fbc22d09c92f6c577254c6c82dfa9967391Robert Phillips                                              SkScalar scaleAdjust[2]) const {
44293798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips    const GrTexture* texture = proxy->priv().peekTexture();
44303798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips    if (!texture) {
44313798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips        // The only way to get and EXTERNAL or RECTANGLE texture in Ganesh is to wrap them.
44323798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips        // In that case the proxy should already be instantiated.
44333798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips        return false;
44343798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips    }
44353798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips
4436e179a9167f71dfc41668b05d40082aae76367fa6bsalomon    if (textureParams.isTiled() ||
4437514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon        GrSamplerParams::kMipMap_FilterMode == textureParams.filterMode()) {
44383798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips        const GrGLTexture* glTexture = static_cast<const GrGLTexture*>(texture);
4439e179a9167f71dfc41668b05d40082aae76367fa6bsalomon        if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() ||
4440e179a9167f71dfc41668b05d40082aae76367fa6bsalomon            GR_GL_TEXTURE_RECTANGLE == glTexture->target()) {
4441514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon            copyParams->fFilter = GrSamplerParams::kNone_FilterMode;
4442e179a9167f71dfc41668b05d40082aae76367fa6bsalomon            copyParams->fWidth = texture->width();
4443e179a9167f71dfc41668b05d40082aae76367fa6bsalomon            copyParams->fHeight = texture->height();
4444e179a9167f71dfc41668b05d40082aae76367fa6bsalomon            return true;
4445e179a9167f71dfc41668b05d40082aae76367fa6bsalomon        }
4446e179a9167f71dfc41668b05d40082aae76367fa6bsalomon    }
4447e179a9167f71dfc41668b05d40082aae76367fa6bsalomon    return false;
4448e179a9167f71dfc41668b05d40082aae76367fa6bsalomon}
444984741b308496409f4ff662658167221fc6801bbejvanverth
44506be35238855dbbc7575e78d6723936293a4b38e6Greg DanielGrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() {
44516be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrGLsync sync;
44526be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
44536be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GR_STATIC_ASSERT(sizeof(GrFence) >= sizeof(GrGLsync));
44546be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    return (GrFence)sync;
445584741b308496409f4ff662658167221fc6801bbejvanverth}
445684741b308496409f4ff662658167221fc6801bbejvanverth
44576be35238855dbbc7575e78d6723936293a4b38e6Greg Danielbool GrGLGpu::waitFence(GrFence fence, uint64_t timeout) {
445884741b308496409f4ff662658167221fc6801bbejvanverth    GrGLenum result;
445984741b308496409f4ff662658167221fc6801bbejvanverth    GL_CALL_RET(result, ClientWaitSync((GrGLsync)fence, GR_GL_SYNC_FLUSH_COMMANDS_BIT, timeout));
446084741b308496409f4ff662658167221fc6801bbejvanverth    return (GR_GL_CONDITION_SATISFIED == result);
446184741b308496409f4ff662658167221fc6801bbejvanverth}
446284741b308496409f4ff662658167221fc6801bbejvanverth
446384741b308496409f4ff662658167221fc6801bbejvanverthvoid GrGLGpu::deleteFence(GrFence fence) const {
44646be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    this->deleteSync((GrGLsync)fence);
44656be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
44666be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
44676be35238855dbbc7575e78d6723936293a4b38e6Greg Danielsk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrGLGpu::makeSemaphore() {
44686be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    return GrGLSemaphore::Make(this);
44696be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
44706be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
44716be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrGLGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore) {
44726be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get());
44736be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
44746be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrGLsync sync;
44756be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
44766be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    glSem->setSync(sync);
44776be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
44786be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
44796be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrGLGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
44806be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get());
44816be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
44826be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GL_CALL(WaitSync(glSem->sync(), 0, GR_GL_TIMEOUT_IGNORED));
44836be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
44846be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
44856be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrGLGpu::deleteSync(GrGLsync sync) const {
44866be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GL_CALL(DeleteSync(sync));
448784741b308496409f4ff662658167221fc6801bbejvanverth}
44882c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman
44892c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osmanvoid GrGLGpu::flush() {
44902c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman    GL_CALL(Flush());
44912c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman}
4492