• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "GrGLGpu.h"
9 
10 #include <cmath>
11 #include "../private/GrGLSL.h"
12 #include "GrBackendSemaphore.h"
13 #include "GrBackendSurface.h"
14 #include "GrFixedClip.h"
15 #include "GrGLBuffer.h"
16 #include "GrGLGpuCommandBuffer.h"
17 #include "GrGLSemaphore.h"
18 #include "GrGLStencilAttachment.h"
19 #include "GrGLTextureRenderTarget.h"
20 #include "GrGpuResourcePriv.h"
21 #include "GrMesh.h"
22 #include "GrPipeline.h"
23 #include "GrRenderTargetPriv.h"
24 #include "GrShaderCaps.h"
25 #include "GrSurfacePriv.h"
26 #include "GrSurfaceProxyPriv.h"
27 #include "GrTexturePriv.h"
28 #include "GrTypes.h"
29 #include "SkAutoMalloc.h"
30 #include "SkMakeUnique.h"
31 #include "SkMipMap.h"
32 #include "SkPixmap.h"
33 #include "SkSLCompiler.h"
34 #include "SkStrokeRec.h"
35 #include "SkTemplates.h"
36 #include "SkTraceEvent.h"
37 #include "SkTypes.h"
38 #include "builders/GrGLShaderStringBuilder.h"
39 #include "instanced/GLInstancedRendering.h"
40 
41 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
42 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
43 
44 #define SKIP_CACHE_CHECK    true
45 
46 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
47     #define CLEAR_ERROR_BEFORE_ALLOC(iface)   GrGLClearErr(iface)
48     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL_NOERRCHECK(iface, call)
49     #define CHECK_ALLOC_ERROR(iface)          GR_GL_GET_ERROR(iface)
50 #else
51     #define CLEAR_ERROR_BEFORE_ALLOC(iface)
52     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL(iface, call)
53     #define CHECK_ALLOC_ERROR(iface)          GR_GL_NO_ERROR
54 #endif
55 
56 //#define USE_NSIGHT
57 
58 ///////////////////////////////////////////////////////////////////////////////
59 
60 using gr_instanced::InstancedRendering;
61 using gr_instanced::GLInstancedRendering;
62 
63 using gr_instanced::OpAllocator;
64 using gr_instanced::GLOpAllocator;
65 
66 static const GrGLenum gXfermodeEquation2Blend[] = {
67     // Basic OpenGL blend equations.
68     GR_GL_FUNC_ADD,
69     GR_GL_FUNC_SUBTRACT,
70     GR_GL_FUNC_REVERSE_SUBTRACT,
71 
72     // GL_KHR_blend_equation_advanced.
73     GR_GL_SCREEN,
74     GR_GL_OVERLAY,
75     GR_GL_DARKEN,
76     GR_GL_LIGHTEN,
77     GR_GL_COLORDODGE,
78     GR_GL_COLORBURN,
79     GR_GL_HARDLIGHT,
80     GR_GL_SOFTLIGHT,
81     GR_GL_DIFFERENCE,
82     GR_GL_EXCLUSION,
83     GR_GL_MULTIPLY,
84     GR_GL_HSL_HUE,
85     GR_GL_HSL_SATURATION,
86     GR_GL_HSL_COLOR,
87     GR_GL_HSL_LUMINOSITY
88 };
89 GR_STATIC_ASSERT(0 == kAdd_GrBlendEquation);
90 GR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation);
91 GR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation);
92 GR_STATIC_ASSERT(3 == kScreen_GrBlendEquation);
93 GR_STATIC_ASSERT(4 == kOverlay_GrBlendEquation);
94 GR_STATIC_ASSERT(5 == kDarken_GrBlendEquation);
95 GR_STATIC_ASSERT(6 == kLighten_GrBlendEquation);
96 GR_STATIC_ASSERT(7 == kColorDodge_GrBlendEquation);
97 GR_STATIC_ASSERT(8 == kColorBurn_GrBlendEquation);
98 GR_STATIC_ASSERT(9 == kHardLight_GrBlendEquation);
99 GR_STATIC_ASSERT(10 == kSoftLight_GrBlendEquation);
100 GR_STATIC_ASSERT(11 == kDifference_GrBlendEquation);
101 GR_STATIC_ASSERT(12 == kExclusion_GrBlendEquation);
102 GR_STATIC_ASSERT(13 == kMultiply_GrBlendEquation);
103 GR_STATIC_ASSERT(14 == kHSLHue_GrBlendEquation);
104 GR_STATIC_ASSERT(15 == kHSLSaturation_GrBlendEquation);
105 GR_STATIC_ASSERT(16 == kHSLColor_GrBlendEquation);
106 GR_STATIC_ASSERT(17 == kHSLLuminosity_GrBlendEquation);
107 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gXfermodeEquation2Blend) == kGrBlendEquationCnt);
108 
109 static const GrGLenum gXfermodeCoeff2Blend[] = {
110     GR_GL_ZERO,
111     GR_GL_ONE,
112     GR_GL_SRC_COLOR,
113     GR_GL_ONE_MINUS_SRC_COLOR,
114     GR_GL_DST_COLOR,
115     GR_GL_ONE_MINUS_DST_COLOR,
116     GR_GL_SRC_ALPHA,
117     GR_GL_ONE_MINUS_SRC_ALPHA,
118     GR_GL_DST_ALPHA,
119     GR_GL_ONE_MINUS_DST_ALPHA,
120     GR_GL_CONSTANT_COLOR,
121     GR_GL_ONE_MINUS_CONSTANT_COLOR,
122     GR_GL_CONSTANT_ALPHA,
123     GR_GL_ONE_MINUS_CONSTANT_ALPHA,
124 
125     // extended blend coeffs
126     GR_GL_SRC1_COLOR,
127     GR_GL_ONE_MINUS_SRC1_COLOR,
128     GR_GL_SRC1_ALPHA,
129     GR_GL_ONE_MINUS_SRC1_ALPHA,
130 };
131 
BlendCoeffReferencesConstant(GrBlendCoeff coeff)132 bool GrGLGpu::BlendCoeffReferencesConstant(GrBlendCoeff coeff) {
133     static const bool gCoeffReferencesBlendConst[] = {
134         false,
135         false,
136         false,
137         false,
138         false,
139         false,
140         false,
141         false,
142         false,
143         false,
144         true,
145         true,
146         true,
147         true,
148 
149         // extended blend coeffs
150         false,
151         false,
152         false,
153         false,
154     };
155     return gCoeffReferencesBlendConst[coeff];
156     GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gCoeffReferencesBlendConst));
157 
158     GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff);
159     GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff);
160     GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff);
161     GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff);
162     GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff);
163     GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff);
164     GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff);
165     GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff);
166     GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff);
167     GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff);
168     GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff);
169     GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff);
170     GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff);
171     GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff);
172 
173     GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff);
174     GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff);
175     GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff);
176     GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff);
177 
178     // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope
179     GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gXfermodeCoeff2Blend));
180 }
181 
182 ///////////////////////////////////////////////////////////////////////////////
183 
184 
Create(GrBackendContext backendContext,const GrContextOptions & options,GrContext * context)185 GrGpu* GrGLGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
186                        GrContext* context) {
187     sk_sp<const GrGLInterface> glInterface(
188         reinterpret_cast<const GrGLInterface*>(backendContext));
189     if (!glInterface) {
190         glInterface.reset(GrGLDefaultInterface());
191     } else {
192         glInterface->ref();
193     }
194     if (!glInterface) {
195         return nullptr;
196     }
197 #ifdef USE_NSIGHT
198     const_cast<GrContextOptions&>(options).fSuppressPathRendering = true;
199 #endif
200     GrGLContext* glContext = GrGLContext::Create(glInterface.get(), options);
201     if (glContext) {
202         return new GrGLGpu(glContext, context);
203     }
204     return nullptr;
205 }
206 
207 static bool gPrintStartupSpew;
208 
GrGLGpu(GrGLContext * ctx,GrContext * context)209 GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
210     : GrGpu(context)
211     , fGLContext(ctx)
212     , fProgramCache(new ProgramCache(this))
213     , fHWProgramID(0)
214     , fTempSrcFBOID(0)
215     , fTempDstFBOID(0)
216     , fStencilClearFBOID(0)
217     , fHWMaxUsedBufferTextureUnit(-1)
218     , fHWMinSampleShading(0.0) {
219     for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
220         fCopyPrograms[i].fProgram = 0;
221     }
222     for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
223         fMipmapPrograms[i].fProgram = 0;
224     }
225     fStencilClipClearProgram = 0;
226 
227     SkASSERT(ctx);
228     fCaps.reset(SkRef(ctx->caps()));
229 
230     fHWBoundTextureUniqueIDs.reset(this->caps()->shaderCaps()->maxCombinedSamplers());
231     fHWBoundImageStorages.reset(this->caps()->shaderCaps()->maxCombinedImageStorages());
232 
233     fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER;
234     fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER;
235     fHWBufferState[kTexel_GrBufferType].fGLTarget = GR_GL_TEXTURE_BUFFER;
236     fHWBufferState[kDrawIndirect_GrBufferType].fGLTarget = GR_GL_DRAW_INDIRECT_BUFFER;
237     if (GrGLCaps::kChromium_TransferBufferType == this->glCaps().transferBufferType()) {
238         fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget =
239             GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM;
240         fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget =
241             GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
242     } else {
243         fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = GR_GL_PIXEL_UNPACK_BUFFER;
244         fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = GR_GL_PIXEL_PACK_BUFFER;
245     }
246     GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState));
247 
248     if (this->caps()->shaderCaps()->texelBufferSupport()) {
249         fHWBufferTextures.reset(this->caps()->shaderCaps()->maxCombinedSamplers());
250     }
251 
252     if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
253         fPathRendering.reset(new GrGLPathRendering(this));
254     }
255 
256     GrGLClearErr(this->glInterface());
257     if (gPrintStartupSpew) {
258         const GrGLubyte* vendor;
259         const GrGLubyte* renderer;
260         const GrGLubyte* version;
261         const GrGLubyte* glslVersion;
262         GL_CALL_RET(vendor, GetString(GR_GL_VENDOR));
263         GL_CALL_RET(renderer, GetString(GR_GL_RENDERER));
264         GL_CALL_RET(version, GetString(GR_GL_VERSION));
265         GL_CALL_RET(glslVersion, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
266         SkDebugf("------------------------- create GrGLGpu %p --------------\n",
267                  this);
268         SkDebugf("------ VENDOR %s\n", vendor);
269         SkDebugf("------ RENDERER %s\n", renderer);
270         SkDebugf("------ VERSION %s\n",  version);
271         SkDebugf("------ SHADING LANGUAGE VERSION %s\n", glslVersion);
272         SkDebugf("------ EXTENSIONS\n");
273         this->glContext().extensions().print();
274         SkDebugf("\n");
275         SkDebugf("%s", this->glCaps().dump().c_str());
276     }
277 }
278 
~GrGLGpu()279 GrGLGpu::~GrGLGpu() {
280     // Ensure any GrGpuResource objects get deleted first, since they may require a working GrGLGpu
281     // to release the resources held by the objects themselves.
282     fPathRendering.reset();
283     fCopyProgramArrayBuffer.reset();
284     fMipmapProgramArrayBuffer.reset();
285     fStencilClipClearArrayBuffer.reset();
286 
287     if (0 != fHWProgramID) {
288         // detach the current program so there is no confusion on OpenGL's part
289         // that we want it to be deleted
290         GL_CALL(UseProgram(0));
291     }
292 
293     if (0 != fTempSrcFBOID) {
294         GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
295     }
296     if (0 != fTempDstFBOID) {
297         GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
298     }
299     if (0 != fStencilClearFBOID) {
300         GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
301     }
302 
303     for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
304         if (0 != fCopyPrograms[i].fProgram) {
305             GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
306         }
307     }
308 
309     for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
310         if (0 != fMipmapPrograms[i].fProgram) {
311             GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram));
312         }
313     }
314 
315     if (0 != fStencilClipClearProgram) {
316         GL_CALL(DeleteProgram(fStencilClipClearProgram));
317     }
318 
319     delete fProgramCache;
320 }
321 
disconnect(DisconnectType type)322 void GrGLGpu::disconnect(DisconnectType type) {
323     INHERITED::disconnect(type);
324     if (DisconnectType::kCleanup == type) {
325         if (fHWProgramID) {
326             GL_CALL(UseProgram(0));
327         }
328         if (fTempSrcFBOID) {
329             GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
330         }
331         if (fTempDstFBOID) {
332             GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
333         }
334         if (fStencilClearFBOID) {
335             GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
336         }
337         for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
338             if (fCopyPrograms[i].fProgram) {
339                 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
340             }
341         }
342         for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
343             if (fMipmapPrograms[i].fProgram) {
344                 GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram));
345             }
346         }
347         if (fStencilClipClearProgram) {
348             GL_CALL(DeleteProgram(fStencilClipClearProgram));
349         }
350     } else {
351         if (fProgramCache) {
352             fProgramCache->abandon();
353         }
354     }
355 
356     delete fProgramCache;
357     fProgramCache = nullptr;
358 
359     fHWProgramID = 0;
360     fTempSrcFBOID = 0;
361     fTempDstFBOID = 0;
362     fStencilClearFBOID = 0;
363     fCopyProgramArrayBuffer.reset();
364     for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
365         fCopyPrograms[i].fProgram = 0;
366     }
367     fMipmapProgramArrayBuffer.reset();
368     for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
369         fMipmapPrograms[i].fProgram = 0;
370     }
371     fStencilClipClearProgram = 0;
372     fStencilClipClearArrayBuffer.reset();
373     if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
374         this->glPathRendering()->disconnect(type);
375     }
376 }
377 
378 ///////////////////////////////////////////////////////////////////////////////
379 
onResetContext(uint32_t resetBits)380 void GrGLGpu::onResetContext(uint32_t resetBits) {
381     if (resetBits & kMisc_GrGLBackendState) {
382         // we don't use the zb at all
383         GL_CALL(Disable(GR_GL_DEPTH_TEST));
384         GL_CALL(DepthMask(GR_GL_FALSE));
385 
386         // We don't use face culling.
387         GL_CALL(Disable(GR_GL_CULL_FACE));
388         // We do use separate stencil. Our algorithms don't care which face is front vs. back so
389         // just set this to the default for self-consistency.
390         GL_CALL(FrontFace(GR_GL_CCW));
391 
392         fHWBufferState[kTexel_GrBufferType].invalidate();
393         fHWBufferState[kDrawIndirect_GrBufferType].invalidate();
394         fHWBufferState[kXferCpuToGpu_GrBufferType].invalidate();
395         fHWBufferState[kXferGpuToCpu_GrBufferType].invalidate();
396 
397         if (kGL_GrGLStandard == this->glStandard()) {
398 #ifndef USE_NSIGHT
399             // Desktop-only state that we never change
400             if (!this->glCaps().isCoreProfile()) {
401                 GL_CALL(Disable(GR_GL_POINT_SMOOTH));
402                 GL_CALL(Disable(GR_GL_LINE_SMOOTH));
403                 GL_CALL(Disable(GR_GL_POLYGON_SMOOTH));
404                 GL_CALL(Disable(GR_GL_POLYGON_STIPPLE));
405                 GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP));
406                 GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP));
407             }
408             // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a
409             // core profile. This seems like a bug since the core spec removes any mention of
410             // GL_ARB_imaging.
411             if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) {
412                 GL_CALL(Disable(GR_GL_COLOR_TABLE));
413             }
414             GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL));
415 
416             if (this->caps()->wireframeMode()) {
417                 GL_CALL(PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_LINE));
418             } else {
419                 GL_CALL(PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_FILL));
420             }
421 #endif
422             // Since ES doesn't support glPointSize at all we always use the VS to
423             // set the point size
424             GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE));
425 
426         }
427 
428         if (kGLES_GrGLStandard == this->glStandard() &&
429                 this->hasExtension("GL_ARM_shader_framebuffer_fetch")) {
430             // The arm extension requires specifically enabling MSAA fetching per sample.
431             // On some devices this may have a perf hit.  Also multiple render targets are disabled
432             GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
433         }
434         fHWWriteToColor = kUnknown_TriState;
435         // we only ever use lines in hairline mode
436         GL_CALL(LineWidth(1));
437         GL_CALL(Disable(GR_GL_DITHER));
438     }
439 
440     if (resetBits & kMSAAEnable_GrGLBackendState) {
441         fMSAAEnabled = kUnknown_TriState;
442 
443         if (this->caps()->usesMixedSamples()) {
444             if (0 != this->caps()->maxRasterSamples()) {
445                 fHWRasterMultisampleEnabled = kUnknown_TriState;
446                 fHWNumRasterSamples = 0;
447             }
448 
449             // The skia blend modes all use premultiplied alpha and therefore expect RGBA coverage
450             // modulation. This state has no effect when not rendering to a mixed sampled target.
451             GL_CALL(CoverageModulation(GR_GL_RGBA));
452         }
453     }
454 
455     fHWActiveTextureUnitIdx = -1; // invalid
456     fLastPrimitiveType = static_cast<GrPrimitiveType>(-1);
457 
458     if (resetBits & kTextureBinding_GrGLBackendState) {
459         for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) {
460             fHWBoundTextureUniqueIDs[s].makeInvalid();
461         }
462         for (int b = 0; b < fHWBufferTextures.count(); ++b) {
463             SkASSERT(this->caps()->shaderCaps()->texelBufferSupport());
464             fHWBufferTextures[b].fKnownBound = false;
465         }
466         for (int i = 0; i < fHWBoundImageStorages.count(); ++i) {
467             SkASSERT(this->caps()->shaderCaps()->imageLoadStoreSupport());
468             fHWBoundImageStorages[i].fTextureUniqueID.makeInvalid();
469         }
470     }
471 
472     if (resetBits & kBlend_GrGLBackendState) {
473         fHWBlendState.invalidate();
474     }
475 
476     if (resetBits & kView_GrGLBackendState) {
477         fHWScissorSettings.invalidate();
478         fHWWindowRectsState.invalidate();
479         fHWViewport.invalidate();
480     }
481 
482     if (resetBits & kStencil_GrGLBackendState) {
483         fHWStencilSettings.invalidate();
484         fHWStencilTestEnabled = kUnknown_TriState;
485     }
486 
487     // Vertex
488     if (resetBits & kVertex_GrGLBackendState) {
489         fHWVertexArrayState.invalidate();
490         fHWBufferState[kVertex_GrBufferType].invalidate();
491         fHWBufferState[kIndex_GrBufferType].invalidate();
492     }
493 
494     if (resetBits & kRenderTarget_GrGLBackendState) {
495         fHWBoundRenderTargetUniqueID.makeInvalid();
496         fHWSRGBFramebuffer = kUnknown_TriState;
497     }
498 
499     if (resetBits & kPathRendering_GrGLBackendState) {
500         if (this->caps()->shaderCaps()->pathRenderingSupport()) {
501             this->glPathRendering()->resetContext();
502         }
503     }
504 
505     // we assume these values
506     if (resetBits & kPixelStore_GrGLBackendState) {
507         if (this->glCaps().unpackRowLengthSupport()) {
508             GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
509         }
510         if (this->glCaps().packRowLengthSupport()) {
511             GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
512         }
513         if (this->glCaps().unpackFlipYSupport()) {
514             GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
515         }
516         if (this->glCaps().packFlipYSupport()) {
517             GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
518         }
519     }
520 
521     if (resetBits & kProgram_GrGLBackendState) {
522         fHWProgramID = 0;
523     }
524 }
525 
onWrapBackendTexture(const GrBackendTexture & backendTex,GrSurfaceOrigin origin,GrBackendTextureFlags flags,int sampleCnt,GrWrapOwnership ownership)526 sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
527                                                GrSurfaceOrigin origin,
528                                                GrBackendTextureFlags flags,
529                                                int sampleCnt,
530                                                GrWrapOwnership ownership) {
531     const GrGLTextureInfo* info = backendTex.getGLTextureInfo();
532     if (!info || !info->fID) {
533         return nullptr;
534     }
535 
536     // next line relies on GrBackendTextureFlags matching GrTexture's
537     bool renderTarget = SkToBool(flags & kRenderTarget_GrBackendTextureFlag);
538 
539     GrGLTexture::IDDesc idDesc;
540     idDesc.fInfo = *info;
541 
542     if (GR_GL_TEXTURE_EXTERNAL == idDesc.fInfo.fTarget) {
543         if (renderTarget) {
544             // This combination is not supported.
545             return nullptr;
546         }
547         if (!this->caps()->shaderCaps()->externalTextureSupport()) {
548             return nullptr;
549         }
550     } else  if (GR_GL_TEXTURE_RECTANGLE == idDesc.fInfo.fTarget) {
551         if (!this->glCaps().rectangleTextureSupport()) {
552             return nullptr;
553         }
554     } else if (GR_GL_TEXTURE_2D != idDesc.fInfo.fTarget) {
555         return nullptr;
556     }
557 
558     // Sample count is interpreted to mean the number of samples that Gr code should allocate
559     // for a render buffer that resolves to the texture. We don't support MSAA textures.
560     if (sampleCnt && !renderTarget) {
561         return nullptr;
562     }
563 
564     if (kBorrow_GrWrapOwnership == ownership) {
565         idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed;
566     } else {
567         idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
568     }
569 
570     GrSurfaceDesc surfDesc;
571     surfDesc.fFlags = (GrSurfaceFlags) flags;
572     surfDesc.fWidth = backendTex.width();
573     surfDesc.fHeight = backendTex.height();
574     surfDesc.fConfig = backendTex.config();
575     surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, backendTex.config());
576     // FIXME:  this should be calling resolve_origin(), but Chrome code is currently
577     // assuming the old behaviour, which is that backend textures are always
578     // BottomLeft, even for non-RT's.  Once Chrome is fixed, change this to:
579     // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
580     if (kDefault_GrSurfaceOrigin == origin) {
581         surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
582     } else {
583         surfDesc.fOrigin = origin;
584     }
585 
586     if (renderTarget) {
587         GrGLRenderTarget::IDDesc rtIDDesc;
588         if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) {
589             return nullptr;
590         }
591         sk_sp<GrGLTextureRenderTarget> texRT(
592                 GrGLTextureRenderTarget::MakeWrapped(this, surfDesc, idDesc, rtIDDesc));
593         texRT->baseLevelWasBoundToFBO();
594         return texRT;
595     }
596 
597     return GrGLTexture::MakeWrapped(this, surfDesc, idDesc);
598 }
599 
onWrapBackendRenderTarget(const GrBackendRenderTarget & backendRT,GrSurfaceOrigin origin)600 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT,
601                                                          GrSurfaceOrigin origin) {
602     const GrGLFramebufferInfo* info = backendRT.getGLFramebufferInfo();
603     if (!info) {
604         return nullptr;
605     }
606 
607     GrGLRenderTarget::IDDesc idDesc;
608     idDesc.fRTFBOID = info->fFBOID;
609     idDesc.fMSColorRenderbufferID = 0;
610     idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
611     idDesc.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed;
612     idDesc.fIsMixedSampled = false;
613 
614     GrSurfaceDesc desc;
615     desc.fConfig = backendRT.config();
616     desc.fFlags = kRenderTarget_GrSurfaceFlag;
617     desc.fWidth = backendRT.width();
618     desc.fHeight = backendRT.height();
619     desc.fSampleCnt = this->caps()->getSampleCount(backendRT.sampleCnt(), backendRT.config());
620     SkASSERT(kDefault_GrSurfaceOrigin != origin);
621     desc.fOrigin = origin;
622 
623     return GrGLRenderTarget::MakeWrapped(this, desc, idDesc, backendRT.stencilBits());
624 }
625 
onWrapBackendTextureAsRenderTarget(const GrBackendTexture & tex,GrSurfaceOrigin origin,int sampleCnt)626 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
627                                                                   GrSurfaceOrigin origin,
628                                                                   int sampleCnt) {
629     const GrGLTextureInfo* info = tex.getGLTextureInfo();
630     if (!info || !info->fID) {
631         return nullptr;
632     }
633 
634     GrGLTextureInfo texInfo;
635     texInfo = *info;
636 
637     if (GR_GL_TEXTURE_RECTANGLE != texInfo.fTarget &&
638         GR_GL_TEXTURE_2D != texInfo.fTarget) {
639         // Only texture rectangle and texture 2d are supported. We do not check whether texture
640         // rectangle is supported by Skia - if the caller provided us with a texture rectangle,
641         // we assume the necessary support exists.
642         return nullptr;
643     }
644 
645     GrSurfaceDesc surfDesc;
646     surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
647     surfDesc.fWidth = tex.width();
648     surfDesc.fHeight = tex.height();
649     surfDesc.fConfig = tex.config();
650     surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, tex.config());
651     // FIXME:  this should be calling resolve_origin(), but Chrome code is currently
652     // assuming the old behaviour, which is that backend textures are always
653     // BottomLeft, even for non-RT's.  Once Chrome is fixed, change this to:
654     // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
655     if (kDefault_GrSurfaceOrigin == origin) {
656         surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
657     } else {
658         surfDesc.fOrigin = origin;
659     }
660 
661     GrGLRenderTarget::IDDesc rtIDDesc;
662     if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) {
663         return nullptr;
664     }
665     return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0);
666 }
667 
668 ////////////////////////////////////////////////////////////////////////////////
669 
onGetWritePixelsInfo(GrSurface * dstSurface,int width,int height,GrPixelConfig srcConfig,DrawPreference * drawPreference,WritePixelTempDrawInfo * tempDrawInfo)670 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
671                                    GrPixelConfig srcConfig,
672                                    DrawPreference* drawPreference,
673                                    WritePixelTempDrawInfo* tempDrawInfo) {
674     if (SkToBool(dstSurface->asRenderTarget())) {
675         if (this->glCaps().useDrawInsteadOfAllRenderTargetWrites()) {
676             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
677         }
678     }
679 
680     GrGLTexture* texture = static_cast<GrGLTexture*>(dstSurface->asTexture());
681 
682     if (texture) {
683         if (GR_GL_TEXTURE_EXTERNAL == texture->target()) {
684              // We don't currently support writing pixels to EXTERNAL textures.
685              return false;
686         }
687         if (GrPixelConfigIsUnorm(texture->config()) && texture->hasBaseLevelBeenBoundToFBO() &&
688             this->glCaps().disallowTexSubImageForUnormConfigTexturesEverBoundToFBO() &&
689             (width < dstSurface->width() || height < dstSurface->height())) {
690             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
691         }
692     } else {
693         // This subclass only allows writes to textures. If the dst is not a texture we have to draw
694         // into it. We could use glDrawPixels on GLs that have it, but we don't today.
695         ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
696     }
697 
698     // If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target.
699     if (dstSurface->asRenderTarget() && dstSurface->asRenderTarget()->numColorSamples() > 0) {
700         ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
701     }
702 
703     if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConfig)) {
704         ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
705     }
706 
707     // Start off assuming no swizzling
708     tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
709     tempDrawInfo->fWriteConfig = srcConfig;
710 
711     // These settings we will always want if a temp draw is performed. Initially set the config
712     // to srcConfig, though that may be modified if we decide to do a R/G swap.
713     tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
714     tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
715     tempDrawInfo->fTempSurfaceDesc.fWidth = width;
716     tempDrawInfo->fTempSurfaceDesc.fHeight = height;
717     tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
718     tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
719 
720     bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
721 
722     if (configsAreRBSwaps) {
723         if (!this->caps()->isConfigTexturable(srcConfig)) {
724             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
725             tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
726             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
727             tempDrawInfo->fWriteConfig = dstSurface->config();
728         } else if (this->glCaps().rgba8888PixelsOpsAreSlow() &&
729                    kRGBA_8888_GrPixelConfig == srcConfig) {
730             ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
731             tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
732             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
733             tempDrawInfo->fWriteConfig = dstSurface->config();
734         } else if (kGLES_GrGLStandard == this->glStandard() &&
735                    this->glCaps().bgraIsInternalFormat()) {
736             // The internal format and external formats must match texture uploads so we can't
737             // swizzle while uploading when BGRA is a distinct internal format.
738             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
739             tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
740             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
741             tempDrawInfo->fWriteConfig = dstSurface->config();
742         }
743     }
744 
745     if (!this->glCaps().unpackFlipYSupport() &&
746         kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) {
747         ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
748     }
749 
750     return true;
751 }
752 
check_write_and_transfer_input(GrGLTexture * glTex,GrSurface * surface,GrPixelConfig config)753 static bool check_write_and_transfer_input(GrGLTexture* glTex, GrSurface* surface,
754                                             GrPixelConfig config) {
755     if (!glTex) {
756         return false;
757     }
758 
759     // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
760     if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
761         return false;
762     }
763 
764     // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textures
765     if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) {
766         return false;
767     }
768 
769     return true;
770 }
771 
onWritePixels(GrSurface * surface,int left,int top,int width,int height,GrPixelConfig config,const GrMipLevel texels[],int mipLevelCount)772 bool GrGLGpu::onWritePixels(GrSurface* surface,
773                             int left, int top, int width, int height,
774                             GrPixelConfig config,
775                             const GrMipLevel texels[],
776                             int mipLevelCount) {
777     GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
778 
779     if (!check_write_and_transfer_input(glTex, surface, config)) {
780         return false;
781     }
782 
783     this->setScratchTextureUnit();
784     GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
785 
786     return this->uploadTexData(glTex->config(), glTex->width(), glTex->height(),
787                                glTex->origin(), glTex->target(), kWrite_UploadType,
788                                left, top, width, height, config, texels, mipLevelCount);
789 }
790 
791 // For GL_[UN]PACK_ALIGNMENT.
config_alignment(GrPixelConfig config)792 static inline GrGLint config_alignment(GrPixelConfig config) {
793     switch (config) {
794         case kAlpha_8_GrPixelConfig:
795         case kGray_8_GrPixelConfig:
796             return 1;
797         case kRGB_565_GrPixelConfig:
798         case kRGBA_4444_GrPixelConfig:
799         case kAlpha_half_GrPixelConfig:
800         case kRGBA_half_GrPixelConfig:
801             return 2;
802         case kRGBA_8888_GrPixelConfig:
803         case kBGRA_8888_GrPixelConfig:
804         case kSRGBA_8888_GrPixelConfig:
805         case kSBGRA_8888_GrPixelConfig:
806         case kRGBA_8888_sint_GrPixelConfig:
807         case kRGBA_float_GrPixelConfig:
808         case kRG_float_GrPixelConfig:
809             return 4;
810         case kUnknown_GrPixelConfig:
811             return 0;
812     }
813     SkFAIL("Invalid pixel config");
814     return 0;
815 }
816 
onTransferPixels(GrTexture * texture,int left,int top,int width,int height,GrPixelConfig config,GrBuffer * transferBuffer,size_t offset,size_t rowBytes)817 bool GrGLGpu::onTransferPixels(GrTexture* texture,
818                                int left, int top, int width, int height,
819                                GrPixelConfig config, GrBuffer* transferBuffer,
820                                size_t offset, size_t rowBytes) {
821     GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
822     GrPixelConfig texConfig = glTex->config();
823     SkASSERT(this->caps()->isConfigTexturable(texConfig));
824 
825     if (!check_write_and_transfer_input(glTex, texture, config)) {
826         return false;
827     }
828 
829     if (width <= 0 || width > SK_MaxS32 || height <= 0 || height > SK_MaxS32) {
830         return false;
831     }
832 
833     this->setScratchTextureUnit();
834     GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
835 
836     SkASSERT(!transferBuffer->isMapped());
837     SkASSERT(!transferBuffer->isCPUBacked());
838     const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer);
839     this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer);
840 
841     SkDEBUGCODE(
842         SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
843         SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
844         SkASSERT(bounds.contains(subRect));
845     )
846 
847     size_t bpp = GrBytesPerPixel(config);
848     const size_t trimRowBytes = width * bpp;
849     if (!rowBytes) {
850         rowBytes = trimRowBytes;
851     }
852     const void* pixels = (void*)offset;
853     if (width < 0 || height < 0) {
854         return false;
855     }
856 
857     bool restoreGLRowLength = false;
858     if (trimRowBytes != rowBytes) {
859         // we should have checked for this support already
860         SkASSERT(this->glCaps().unpackRowLengthSupport());
861         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowBytes / bpp));
862         restoreGLRowLength = true;
863     }
864 
865     // Internal format comes from the texture desc.
866     GrGLenum internalFormat;
867     // External format and type come from the upload data.
868     GrGLenum externalFormat;
869     GrGLenum externalType;
870     if (!this->glCaps().getTexImageFormats(texConfig, config, &internalFormat,
871                                            &externalFormat, &externalType)) {
872         return false;
873     }
874 
875     GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(texConfig)));
876     GL_CALL(TexSubImage2D(glTex->target(),
877                           0,
878                           left, top,
879                           width,
880                           height,
881                           externalFormat, externalType,
882                           pixels));
883 
884     if (restoreGLRowLength) {
885         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
886     }
887 
888     return true;
889 }
890 
891 /**
892  * Creates storage space for the texture and fills it with texels.
893  *
894  * @param config         Pixel config of the texture.
895  * @param interface      The GL interface in use.
896  * @param caps           The capabilities of the GL device.
897  * @param internalFormat The data format used for the internal storage of the texture. May be sized.
898  * @param internalFormatForTexStorage The data format used for the TexStorage API. Must be sized.
899  * @param externalFormat The data format used for the external storage of the texture.
900  * @param externalType   The type of the data used for the external storage of the texture.
901  * @param texels         The texel data of the texture being created.
902  * @param baseWidth      The width of the texture's base mipmap level
903  * @param baseHeight     The height of the texture's base mipmap level
904  */
allocate_and_populate_texture(GrPixelConfig config,const GrGLInterface & interface,const GrGLCaps & caps,GrGLenum target,GrGLenum internalFormat,GrGLenum internalFormatForTexStorage,GrGLenum externalFormat,GrGLenum externalType,const GrMipLevel texels[],int mipLevelCount,int baseWidth,int baseHeight)905 static bool allocate_and_populate_texture(GrPixelConfig config,
906                                           const GrGLInterface& interface,
907                                           const GrGLCaps& caps,
908                                           GrGLenum target,
909                                           GrGLenum internalFormat,
910                                           GrGLenum internalFormatForTexStorage,
911                                           GrGLenum externalFormat,
912                                           GrGLenum externalType,
913                                           const GrMipLevel texels[], int mipLevelCount,
914                                           int baseWidth, int baseHeight) {
915     CLEAR_ERROR_BEFORE_ALLOC(&interface);
916 
917     bool useTexStorage = caps.isConfigTexSupportEnabled(config);
918     // We can only use TexStorage if we know we will not later change the storage requirements.
919     // This means if we may later want to add mipmaps, we cannot use TexStorage.
920     // Right now, we cannot know if we will later add mipmaps or not.
921     // The only time we can use TexStorage is when we already have the
922     // mipmaps or are using a format incompatible with MIP maps.
923     useTexStorage &= mipLevelCount > 1 || GrPixelConfigIsSint(config);
924 
925     if (useTexStorage) {
926         // We never resize or change formats of textures.
927         GL_ALLOC_CALL(&interface,
928                       TexStorage2D(target, SkTMax(mipLevelCount, 1), internalFormatForTexStorage,
929                                    baseWidth, baseHeight));
930         GrGLenum error = CHECK_ALLOC_ERROR(&interface);
931         if (error != GR_GL_NO_ERROR) {
932             return  false;
933         } else {
934             for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
935                 const void* currentMipData = texels[currentMipLevel].fPixels;
936                 if (currentMipData == nullptr) {
937                     continue;
938                 }
939                 int twoToTheMipLevel = 1 << currentMipLevel;
940                 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
941                 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
942 
943                 GR_GL_CALL(&interface,
944                            TexSubImage2D(target,
945                                          currentMipLevel,
946                                          0, // left
947                                          0, // top
948                                          currentWidth,
949                                          currentHeight,
950                                          externalFormat, externalType,
951                                          currentMipData));
952             }
953             return true;
954         }
955     } else {
956         if (!mipLevelCount) {
957             GL_ALLOC_CALL(&interface,
958                           TexImage2D(target,
959                                      0,
960                                      internalFormat,
961                                      baseWidth,
962                                      baseHeight,
963                                      0, // border
964                                      externalFormat, externalType,
965                                      nullptr));
966             GrGLenum error = CHECK_ALLOC_ERROR(&interface);
967             if (error != GR_GL_NO_ERROR) {
968                 return false;
969             }
970         } else {
971             for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
972                 int twoToTheMipLevel = 1 << currentMipLevel;
973                 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
974                 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
975                 const void* currentMipData = texels[currentMipLevel].fPixels;
976                 // Even if curremtMipData is nullptr, continue to call TexImage2D.
977                 // This will allocate texture memory which we can later populate.
978                 GL_ALLOC_CALL(&interface,
979                               TexImage2D(target,
980                                          currentMipLevel,
981                                          internalFormat,
982                                          currentWidth,
983                                          currentHeight,
984                                          0, // border
985                                          externalFormat, externalType,
986                                          currentMipData));
987                 GrGLenum error = CHECK_ALLOC_ERROR(&interface);
988                 if (error != GR_GL_NO_ERROR) {
989                     return false;
990                 }
991             }
992         }
993     }
994     return true;
995 }
996 
997 /**
998  * After a texture is created, any state which was altered during its creation
999  * needs to be restored.
1000  *
1001  * @param interface          The GL interface to use.
1002  * @param caps               The capabilities of the GL device.
1003  * @param restoreGLRowLength Should the row length unpacking be restored?
1004  * @param glFlipY            Did GL flip the texture vertically?
1005  */
restore_pixelstore_state(const GrGLInterface & interface,const GrGLCaps & caps,bool restoreGLRowLength,bool glFlipY)1006 static void restore_pixelstore_state(const GrGLInterface& interface, const GrGLCaps& caps,
1007                                      bool restoreGLRowLength, bool glFlipY) {
1008     if (restoreGLRowLength) {
1009         SkASSERT(caps.unpackRowLengthSupport());
1010         GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
1011     }
1012     if (glFlipY) {
1013         GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
1014     }
1015 }
1016 
uploadTexData(GrPixelConfig texConfig,int texWidth,int texHeight,GrSurfaceOrigin texOrigin,GrGLenum target,UploadType uploadType,int left,int top,int width,int height,GrPixelConfig dataConfig,const GrMipLevel texels[],int mipLevelCount)1017 bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
1018                             GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType,
1019                             int left, int top, int width, int height, GrPixelConfig dataConfig,
1020                             const GrMipLevel texels[], int mipLevelCount) {
1021     SkASSERT(this->caps()->isConfigTexturable(texConfig));
1022     SkDEBUGCODE(
1023         SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
1024         SkIRect bounds = SkIRect::MakeWH(texWidth, texHeight);
1025         SkASSERT(bounds.contains(subRect));
1026     )
1027     SkASSERT(1 == mipLevelCount ||
1028              (0 == left && 0 == top && width == texWidth && height == texHeight));
1029 
1030     // unbind any previous transfer buffer
1031     auto& xferBufferState = fHWBufferState[kXferCpuToGpu_GrBufferType];
1032     if (!xferBufferState.fBoundBufferUniqueID.isInvalid()) {
1033         GL_CALL(BindBuffer(xferBufferState.fGLTarget, 0));
1034         xferBufferState.invalidate();
1035     }
1036 
1037     // texels is const.
1038     // But we may need to flip the texture vertically to prepare it.
1039     // Rather than flip in place and alter the incoming data,
1040     // we allocate a new buffer to flip into.
1041     // This means we need to make a non-const shallow copy of texels.
1042     SkAutoTMalloc<GrMipLevel> texelsShallowCopy;
1043 
1044     if (mipLevelCount) {
1045         texelsShallowCopy.reset(mipLevelCount);
1046         memcpy(texelsShallowCopy.get(), texels, mipLevelCount*sizeof(GrMipLevel));
1047     }
1048 
1049     for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; ++currentMipLevel) {
1050         SkASSERT(texelsShallowCopy[currentMipLevel].fPixels);
1051     }
1052 
1053     const GrGLInterface* interface = this->glInterface();
1054     const GrGLCaps& caps = this->glCaps();
1055 
1056     size_t bpp = GrBytesPerPixel(dataConfig);
1057 
1058     if (width == 0 || height == 0) {
1059         return false;
1060     }
1061 
1062     // Internal format comes from the texture desc.
1063     GrGLenum internalFormat;
1064     // External format and type come from the upload data.
1065     GrGLenum externalFormat;
1066     GrGLenum externalType;
1067     if (!this->glCaps().getTexImageFormats(texConfig, dataConfig, &internalFormat, &externalFormat,
1068                                            &externalType)) {
1069         return false;
1070     }
1071     // TexStorage requires a sized format, and internalFormat may or may not be
1072     GrGLenum internalFormatForTexStorage = this->glCaps().configSizedInternalFormat(texConfig);
1073 
1074     /*
1075      *  Check whether to allocate a temporary buffer for flipping y or
1076      *  because our srcData has extra bytes past each row. If so, we need
1077      *  to trim those off here, since GL ES may not let us specify
1078      *  GL_UNPACK_ROW_LENGTH.
1079      */
1080     bool restoreGLRowLength = false;
1081     bool swFlipY = false;
1082     bool glFlipY = false;
1083 
1084     if (kBottomLeft_GrSurfaceOrigin == texOrigin && mipLevelCount) {
1085         if (caps.unpackFlipYSupport()) {
1086             glFlipY = true;
1087         } else {
1088             swFlipY = true;
1089         }
1090     }
1091 
1092     // in case we need a temporary, trimmed copy of the src pixels
1093     SkAutoSMalloc<128 * 128> tempStorage;
1094 
1095     // find the combined size of all the mip levels and the relative offset of
1096     // each into the collective buffer
1097     size_t combined_buffer_size = 0;
1098     SkTArray<size_t> individual_mip_offsets(mipLevelCount);
1099     for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
1100         int twoToTheMipLevel = 1 << currentMipLevel;
1101         int currentWidth = SkTMax(1, width / twoToTheMipLevel);
1102         int currentHeight = SkTMax(1, height / twoToTheMipLevel);
1103         const size_t trimmedSize = currentWidth * bpp * currentHeight;
1104         individual_mip_offsets.push_back(combined_buffer_size);
1105         combined_buffer_size += trimmedSize;
1106     }
1107     char* buffer = (char*)tempStorage.reset(combined_buffer_size);
1108 
1109     for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
1110         int twoToTheMipLevel = 1 << currentMipLevel;
1111         int currentWidth = SkTMax(1, width / twoToTheMipLevel);
1112         int currentHeight = SkTMax(1, height / twoToTheMipLevel);
1113         const size_t trimRowBytes = currentWidth * bpp;
1114 
1115         /*
1116          *  check whether to allocate a temporary buffer for flipping y or
1117          *  because our srcData has extra bytes past each row. If so, we need
1118          *  to trim those off here, since GL ES may not let us specify
1119          *  GL_UNPACK_ROW_LENGTH.
1120          */
1121         restoreGLRowLength = false;
1122 
1123         const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes ?
1124                                 texelsShallowCopy[currentMipLevel].fRowBytes :
1125                                 trimRowBytes;
1126 
1127         // TODO: This optimization should be enabled with or without mips.
1128         // For use with mips, we must set GR_GL_UNPACK_ROW_LENGTH once per
1129         // mip level, before calling glTexImage2D.
1130         const bool usesMips = mipLevelCount > 1;
1131         if (caps.unpackRowLengthSupport() && !swFlipY && !usesMips) {
1132             // can't use this for flipping, only non-neg values allowed. :(
1133             if (rowBytes != trimRowBytes) {
1134                 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
1135                 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
1136                 restoreGLRowLength = true;
1137             }
1138         } else if (trimRowBytes != rowBytes || swFlipY) {
1139             // copy data into our new storage, skipping the trailing bytes
1140             const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels;
1141             if (swFlipY && currentHeight >= 1) {
1142                 src += (currentHeight - 1) * rowBytes;
1143             }
1144             char* dst = buffer + individual_mip_offsets[currentMipLevel];
1145             for (int y = 0; y < currentHeight; y++) {
1146                 memcpy(dst, src, trimRowBytes);
1147                 if (swFlipY) {
1148                     src -= rowBytes;
1149                 } else {
1150                     src += rowBytes;
1151                 }
1152                 dst += trimRowBytes;
1153             }
1154             // now point data to our copied version
1155             texelsShallowCopy[currentMipLevel].fPixels = buffer +
1156                 individual_mip_offsets[currentMipLevel];
1157             texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes;
1158         }
1159     }
1160 
1161     if (mipLevelCount) {
1162         if (glFlipY) {
1163             GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
1164         }
1165         GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(texConfig)));
1166     }
1167 
1168     bool succeeded = true;
1169     if (kNewTexture_UploadType == uploadType) {
1170         if (0 == left && 0 == top && texWidth == width && texHeight == height) {
1171             succeeded = allocate_and_populate_texture(
1172                     texConfig, *interface, caps, target, internalFormat,
1173                     internalFormatForTexStorage, externalFormat, externalType,
1174                     texelsShallowCopy, mipLevelCount, width, height);
1175         } else {
1176             succeeded = false;
1177         }
1178     } else {
1179         if (swFlipY || glFlipY) {
1180             top = texHeight - (top + height);
1181         }
1182         for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
1183             int twoToTheMipLevel = 1 << currentMipLevel;
1184             int currentWidth = SkTMax(1, width / twoToTheMipLevel);
1185             int currentHeight = SkTMax(1, height / twoToTheMipLevel);
1186 
1187             GL_CALL(TexSubImage2D(target,
1188                                   currentMipLevel,
1189                                   left, top,
1190                                   currentWidth,
1191                                   currentHeight,
1192                                   externalFormat, externalType,
1193                                   texelsShallowCopy[currentMipLevel].fPixels));
1194         }
1195     }
1196 
1197     restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY);
1198 
1199     return succeeded;
1200 }
1201 
renderbuffer_storage_msaa(const GrGLContext & ctx,int sampleCount,GrGLenum format,int width,int height)1202 static bool renderbuffer_storage_msaa(const GrGLContext& ctx,
1203                                       int sampleCount,
1204                                       GrGLenum format,
1205                                       int width, int height) {
1206     CLEAR_ERROR_BEFORE_ALLOC(ctx.interface());
1207     SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType());
1208     switch (ctx.caps()->msFBOType()) {
1209         case GrGLCaps::kStandard_MSFBOType:
1210         case GrGLCaps::kMixedSamples_MSFBOType:
1211             GL_ALLOC_CALL(ctx.interface(),
1212                             RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
1213                                                             sampleCount,
1214                                                             format,
1215                                                             width, height));
1216             break;
1217         case GrGLCaps::kES_Apple_MSFBOType:
1218             GL_ALLOC_CALL(ctx.interface(),
1219                             RenderbufferStorageMultisampleES2APPLE(GR_GL_RENDERBUFFER,
1220                                                                     sampleCount,
1221                                                                     format,
1222                                                                     width, height));
1223             break;
1224         case GrGLCaps::kES_EXT_MsToTexture_MSFBOType:
1225         case GrGLCaps::kES_IMG_MsToTexture_MSFBOType:
1226             GL_ALLOC_CALL(ctx.interface(),
1227                             RenderbufferStorageMultisampleES2EXT(GR_GL_RENDERBUFFER,
1228                                                                 sampleCount,
1229                                                                 format,
1230                                                                 width, height));
1231             break;
1232         case GrGLCaps::kNone_MSFBOType:
1233             SkFAIL("Shouldn't be here if we don't support multisampled renderbuffers.");
1234             break;
1235     }
1236     return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface()));
1237 }
1238 
createRenderTargetObjects(const GrSurfaceDesc & desc,const GrGLTextureInfo & texInfo,GrGLRenderTarget::IDDesc * idDesc)1239 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
1240                                         const GrGLTextureInfo& texInfo,
1241                                         GrGLRenderTarget::IDDesc* idDesc) {
1242     idDesc->fMSColorRenderbufferID = 0;
1243     idDesc->fRTFBOID = 0;
1244     idDesc->fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
1245     idDesc->fTexFBOID = 0;
1246     SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) ==
1247              this->caps()->usesMixedSamples());
1248     idDesc->fIsMixedSampled = desc.fSampleCnt > 0 && this->caps()->usesMixedSamples();
1249 
1250     GrGLenum status;
1251 
1252     GrGLenum colorRenderbufferFormat = 0; // suppress warning
1253 
1254     if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
1255         goto FAILED;
1256     }
1257 
1258     GL_CALL(GenFramebuffers(1, &idDesc->fTexFBOID));
1259     if (!idDesc->fTexFBOID) {
1260         goto FAILED;
1261     }
1262 
1263     // If we are using multisampling we will create two FBOS. We render to one and then resolve to
1264     // the texture bound to the other. The exception is the IMG multisample extension. With this
1265     // extension the texture is multisampled when rendered to and then auto-resolves it when it is
1266     // rendered from.
1267     if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) {
1268         GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID));
1269         GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID));
1270         if (!idDesc->fRTFBOID ||
1271             !idDesc->fMSColorRenderbufferID) {
1272             goto FAILED;
1273         }
1274         if (!this->glCaps().getRenderbufferFormat(desc.fConfig, &colorRenderbufferFormat)) {
1275             return false;
1276         }
1277     } else {
1278         idDesc->fRTFBOID = idDesc->fTexFBOID;
1279     }
1280 
1281     // below here we may bind the FBO
1282     fHWBoundRenderTargetUniqueID.makeInvalid();
1283     if (idDesc->fRTFBOID != idDesc->fTexFBOID) {
1284         SkASSERT(desc.fSampleCnt > 0);
1285         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbufferID));
1286         if (!renderbuffer_storage_msaa(*fGLContext,
1287                                        desc.fSampleCnt,
1288                                        colorRenderbufferFormat,
1289                                        desc.fWidth, desc.fHeight)) {
1290             goto FAILED;
1291         }
1292         fStats.incRenderTargetBinds();
1293         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID));
1294         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1295                                         GR_GL_COLOR_ATTACHMENT0,
1296                                         GR_GL_RENDERBUFFER,
1297                                         idDesc->fMSColorRenderbufferID));
1298         if (!this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) {
1299             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1300             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
1301                 goto FAILED;
1302             }
1303             fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
1304         }
1305     }
1306     fStats.incRenderTargetBinds();
1307     GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID));
1308 
1309     if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) {
1310         GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
1311                                                 GR_GL_COLOR_ATTACHMENT0,
1312                                                 texInfo.fTarget,
1313                                                 texInfo.fID, 0, desc.fSampleCnt));
1314     } else {
1315         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
1316                                      GR_GL_COLOR_ATTACHMENT0,
1317                                      texInfo.fTarget,
1318                                      texInfo.fID, 0));
1319     }
1320     if (!this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) {
1321         GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1322         if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
1323             goto FAILED;
1324         }
1325         fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
1326     }
1327 
1328     return true;
1329 
1330 FAILED:
1331     if (idDesc->fMSColorRenderbufferID) {
1332         GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID));
1333     }
1334     if (idDesc->fRTFBOID != idDesc->fTexFBOID) {
1335         GL_CALL(DeleteFramebuffers(1, &idDesc->fRTFBOID));
1336     }
1337     if (idDesc->fTexFBOID) {
1338         GL_CALL(DeleteFramebuffers(1, &idDesc->fTexFBOID));
1339     }
1340     return false;
1341 }
1342 
1343 // good to set a break-point here to know when createTexture fails
return_null_texture()1344 static sk_sp<GrTexture> return_null_texture() {
1345 //    SkDEBUGFAIL("null texture");
1346     return nullptr;
1347 }
1348 
1349 #if 0 && defined(SK_DEBUG)
1350 static size_t as_size_t(int x) {
1351     return x;
1352 }
1353 #endif
1354 
set_initial_texture_params(const GrGLInterface * interface,const GrGLTextureInfo & info,GrGLTexture::TexParams * initialTexParams)1355 static void set_initial_texture_params(const GrGLInterface* interface,
1356                                        const GrGLTextureInfo& info,
1357                                        GrGLTexture::TexParams* initialTexParams) {
1358     // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
1359     // drivers have a bug where an FBO won't be complete if it includes a
1360     // texture that is not mipmap complete (considering the filter in use).
1361     // we only set a subset here so invalidate first
1362     initialTexParams->invalidate();
1363     initialTexParams->fMinFilter = GR_GL_NEAREST;
1364     initialTexParams->fMagFilter = GR_GL_NEAREST;
1365     initialTexParams->fWrapS = GR_GL_CLAMP_TO_EDGE;
1366     initialTexParams->fWrapT = GR_GL_CLAMP_TO_EDGE;
1367     GR_GL_CALL(interface, TexParameteri(info.fTarget,
1368                                         GR_GL_TEXTURE_MAG_FILTER,
1369                                         initialTexParams->fMagFilter));
1370     GR_GL_CALL(interface, TexParameteri(info.fTarget,
1371                                         GR_GL_TEXTURE_MIN_FILTER,
1372                                         initialTexParams->fMinFilter));
1373     GR_GL_CALL(interface, TexParameteri(info.fTarget,
1374                                         GR_GL_TEXTURE_WRAP_S,
1375                                         initialTexParams->fWrapS));
1376     GR_GL_CALL(interface, TexParameteri(info.fTarget,
1377                                         GR_GL_TEXTURE_WRAP_T,
1378                                         initialTexParams->fWrapT));
1379 }
1380 
onCreateTexture(const GrSurfaceDesc & desc,SkBudgeted budgeted,const GrMipLevel texels[],int mipLevelCount)1381 sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
1382                                           SkBudgeted budgeted,
1383                                           const GrMipLevel texels[],
1384                                           int mipLevelCount) {
1385     // We fail if the MSAA was requested and is not available.
1386     if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) {
1387         //SkDebugf("MSAA RT requested but not supported on this platform.");
1388         return return_null_texture();
1389     }
1390 
1391     bool performClear = (desc.fFlags & kPerformInitialClear_GrSurfaceFlag);
1392 
1393     GrMipLevel zeroLevel;
1394     std::unique_ptr<uint8_t[]> zeros;
1395     // TODO: remove the GrPixelConfigIsSint test. This is here because we have yet to add support
1396     // for glClearBuffer* which must be used instead of glClearColor/glClear for integer FBO
1397     // attachments.
1398     if (performClear && !this->glCaps().clearTextureSupport() &&
1399         (!this->glCaps().canConfigBeFBOColorAttachment(desc.fConfig) ||
1400          GrPixelConfigIsSint(desc.fConfig))) {
1401         size_t rowSize = GrBytesPerPixel(desc.fConfig) * desc.fWidth;
1402         size_t size = rowSize * desc.fHeight;
1403         zeros.reset(new uint8_t[size]);
1404         memset(zeros.get(), 0, size);
1405         zeroLevel.fPixels = zeros.get();
1406         zeroLevel.fRowBytes = 0;
1407         texels = &zeroLevel;
1408         mipLevelCount = 1;
1409         performClear = false;
1410     }
1411 
1412     bool isRenderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
1413 
1414     GrGLTexture::IDDesc idDesc;
1415     idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
1416     GrGLTexture::TexParams initialTexParams;
1417     if (!this->createTextureImpl(desc, &idDesc.fInfo, isRenderTarget, &initialTexParams,
1418                                  texels, mipLevelCount)) {
1419         return return_null_texture();
1420     }
1421 
1422     bool wasMipMapDataProvided = false;
1423     if (mipLevelCount > 1) {
1424         wasMipMapDataProvided = true;
1425     }
1426 
1427     sk_sp<GrGLTexture> tex;
1428     if (isRenderTarget) {
1429         // unbind the texture from the texture unit before binding it to the frame buffer
1430         GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0));
1431         GrGLRenderTarget::IDDesc rtIDDesc;
1432 
1433         if (!this->createRenderTargetObjects(desc, idDesc.fInfo, &rtIDDesc)) {
1434             GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
1435             return return_null_texture();
1436         }
1437         tex = sk_make_sp<GrGLTextureRenderTarget>(this, budgeted, desc, idDesc, rtIDDesc,
1438                                                   wasMipMapDataProvided);
1439         tex->baseLevelWasBoundToFBO();
1440     } else {
1441         tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc, wasMipMapDataProvided);
1442     }
1443     tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1444 #ifdef TRACE_TEXTURE_CREATION
1445     SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
1446              idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
1447 #endif
1448     if (tex && performClear) {
1449         if (this->glCaps().clearTextureSupport()) {
1450             GrGLenum format = GrPixelConfigIsSint(tex->config()) ? GR_GL_RGBA_INTEGER : GR_GL_RGBA;
1451             static constexpr uint32_t kZero = 0;
1452             GL_CALL(ClearTexImage(tex->textureID(), 0, format, GR_GL_UNSIGNED_BYTE, &kZero));
1453         } else {
1454             SkASSERT(!GrPixelConfigIsSint(desc.fConfig));
1455             GrGLIRect viewport;
1456             this->bindSurfaceFBOForPixelOps(tex.get(), GR_GL_FRAMEBUFFER, &viewport,
1457                                             kDst_TempFBOTarget);
1458             this->disableScissor();
1459             this->disableWindowRectangles();
1460             GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
1461             fHWWriteToColor = kYes_TriState;
1462             GL_CALL(ClearColor(0, 0, 0, 0));
1463             GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
1464             this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, tex.get());
1465             fHWBoundRenderTargetUniqueID.makeInvalid();
1466         }
1467     }
1468     return tex;
1469 }
1470 
1471 namespace {
1472 
1473 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
1474 
get_stencil_rb_sizes(const GrGLInterface * gl,GrGLStencilAttachment::Format * format)1475 void inline get_stencil_rb_sizes(const GrGLInterface* gl,
1476                                  GrGLStencilAttachment::Format* format) {
1477 
1478     // we shouldn't ever know one size and not the other
1479     SkASSERT((kUnknownBitCount == format->fStencilBits) ==
1480              (kUnknownBitCount == format->fTotalBits));
1481     if (kUnknownBitCount == format->fStencilBits) {
1482         GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1483                                          GR_GL_RENDERBUFFER_STENCIL_SIZE,
1484                                          (GrGLint*)&format->fStencilBits);
1485         if (format->fPacked) {
1486             GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1487                                              GR_GL_RENDERBUFFER_DEPTH_SIZE,
1488                                              (GrGLint*)&format->fTotalBits);
1489             format->fTotalBits += format->fStencilBits;
1490         } else {
1491             format->fTotalBits = format->fStencilBits;
1492         }
1493     }
1494 }
1495 }
1496 
getCompatibleStencilIndex(GrPixelConfig config)1497 int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
1498     static const int kSize = 16;
1499     SkASSERT(this->caps()->isConfigRenderable(config, false));
1500     if (!this->glCaps().hasStencilFormatBeenDeterminedForConfig(config)) {
1501         // Default to unsupported, set this if we find a stencil format that works.
1502         int firstWorkingStencilFormatIndex = -1;
1503         // Create color texture
1504         GrGLuint colorID = 0;
1505         GL_CALL(GenTextures(1, &colorID));
1506         this->setScratchTextureUnit();
1507         GL_CALL(BindTexture(GR_GL_TEXTURE_2D, colorID));
1508         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1509                               GR_GL_TEXTURE_MAG_FILTER,
1510                               GR_GL_NEAREST));
1511         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1512                               GR_GL_TEXTURE_MIN_FILTER,
1513                               GR_GL_NEAREST));
1514         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1515                               GR_GL_TEXTURE_WRAP_S,
1516                               GR_GL_CLAMP_TO_EDGE));
1517         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1518                               GR_GL_TEXTURE_WRAP_T,
1519                               GR_GL_CLAMP_TO_EDGE));
1520 
1521         GrGLenum internalFormat;
1522         GrGLenum externalFormat;
1523         GrGLenum externalType;
1524         if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat,
1525                                                &externalType)) {
1526             return false;
1527         }
1528         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1529         GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D,
1530                                                       0,
1531                                                       internalFormat,
1532                                                       kSize,
1533                                                       kSize,
1534                                                       0,
1535                                                       externalFormat,
1536                                                       externalType,
1537                                                       NULL));
1538         if (GR_GL_NO_ERROR != CHECK_ALLOC_ERROR(this->glInterface())) {
1539             GL_CALL(DeleteTextures(1, &colorID));
1540             return -1;
1541         }
1542 
1543         // unbind the texture from the texture unit before binding it to the frame buffer
1544         GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0));
1545 
1546         // Create Framebuffer
1547         GrGLuint fb = 0;
1548         GL_CALL(GenFramebuffers(1, &fb));
1549         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fb));
1550         fHWBoundRenderTargetUniqueID.makeInvalid();
1551         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
1552                                      GR_GL_COLOR_ATTACHMENT0,
1553                                      GR_GL_TEXTURE_2D,
1554                                      colorID,
1555                                      0));
1556         GrGLuint sbRBID = 0;
1557         GL_CALL(GenRenderbuffers(1, &sbRBID));
1558 
1559         // look over formats till I find a compatible one
1560         int stencilFmtCnt = this->glCaps().stencilFormats().count();
1561         if (sbRBID) {
1562             GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbRBID));
1563             for (int i = 0; i < stencilFmtCnt && sbRBID; ++i) {
1564                 const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[i];
1565                 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1566                 GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
1567                                                                        sFmt.fInternalFormat,
1568                                                                        kSize, kSize));
1569                 if (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface())) {
1570                     GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1571                                                     GR_GL_STENCIL_ATTACHMENT,
1572                                                     GR_GL_RENDERBUFFER, sbRBID));
1573                     if (sFmt.fPacked) {
1574                         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1575                                                         GR_GL_DEPTH_ATTACHMENT,
1576                                                         GR_GL_RENDERBUFFER, sbRBID));
1577                     } else {
1578                         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1579                                                         GR_GL_DEPTH_ATTACHMENT,
1580                                                         GR_GL_RENDERBUFFER, 0));
1581                     }
1582                     GrGLenum status;
1583                     GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1584                     if (status == GR_GL_FRAMEBUFFER_COMPLETE) {
1585                         firstWorkingStencilFormatIndex = i;
1586                         break;
1587                     }
1588                     GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1589                                                     GR_GL_STENCIL_ATTACHMENT,
1590                                                     GR_GL_RENDERBUFFER, 0));
1591                     if (sFmt.fPacked) {
1592                         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1593                                                         GR_GL_DEPTH_ATTACHMENT,
1594                                                         GR_GL_RENDERBUFFER, 0));
1595                     }
1596                 }
1597             }
1598             GL_CALL(DeleteRenderbuffers(1, &sbRBID));
1599         }
1600         GL_CALL(DeleteTextures(1, &colorID));
1601         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
1602         GL_CALL(DeleteFramebuffers(1, &fb));
1603         fGLContext->caps()->setStencilFormatIndexForConfig(config, firstWorkingStencilFormatIndex);
1604     }
1605     return this->glCaps().getStencilFormatIndexForConfig(config);
1606 }
1607 
createTextureImpl(const GrSurfaceDesc & desc,GrGLTextureInfo * info,bool renderTarget,GrGLTexture::TexParams * initialTexParams,const GrMipLevel texels[],int mipLevelCount)1608 bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
1609                                 bool renderTarget, GrGLTexture::TexParams* initialTexParams,
1610                                 const GrMipLevel texels[], int mipLevelCount) {
1611     info->fID = 0;
1612     info->fTarget = GR_GL_TEXTURE_2D;
1613     GL_CALL(GenTextures(1, &(info->fID)));
1614 
1615     if (!info->fID) {
1616         return false;
1617     }
1618 
1619     this->setScratchTextureUnit();
1620     GL_CALL(BindTexture(info->fTarget, info->fID));
1621 
1622     if (renderTarget && this->glCaps().textureUsageSupport()) {
1623         // provides a hint about how this texture will be used
1624         GL_CALL(TexParameteri(info->fTarget,
1625                               GR_GL_TEXTURE_USAGE,
1626                               GR_GL_FRAMEBUFFER_ATTACHMENT));
1627     }
1628 
1629     if (info) {
1630         set_initial_texture_params(this->glInterface(), *info, initialTexParams);
1631     }
1632     if (!this->uploadTexData(desc.fConfig, desc.fWidth, desc.fHeight, desc.fOrigin, info->fTarget,
1633                              kNewTexture_UploadType, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
1634                              texels, mipLevelCount)) {
1635         GL_CALL(DeleteTextures(1, &(info->fID)));
1636         return false;
1637     }
1638     return true;
1639 }
1640 
createStencilAttachmentForRenderTarget(const GrRenderTarget * rt,int width,int height)1641 GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
1642                                                                      int width, int height) {
1643     SkASSERT(width >= rt->width());
1644     SkASSERT(height >= rt->height());
1645 
1646     int samples = rt->numStencilSamples();
1647     GrGLStencilAttachment::IDDesc sbDesc;
1648 
1649     int sIdx = this->getCompatibleStencilIndex(rt->config());
1650     if (sIdx < 0) {
1651         return nullptr;
1652     }
1653 
1654     if (!sbDesc.fRenderbufferID) {
1655         GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID));
1656     }
1657     if (!sbDesc.fRenderbufferID) {
1658         return nullptr;
1659     }
1660     GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID));
1661     const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx];
1662     CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1663     // we do this "if" so that we don't call the multisample
1664     // version on a GL that doesn't have an MSAA extension.
1665     if (samples > 0) {
1666         SkAssertResult(renderbuffer_storage_msaa(*fGLContext,
1667                                                  samples,
1668                                                  sFmt.fInternalFormat,
1669                                                  width, height));
1670     } else {
1671         GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
1672                                                                sFmt.fInternalFormat,
1673                                                                width, height));
1674         SkASSERT(GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(this->glInterface()));
1675     }
1676     fStats.incStencilAttachmentCreates();
1677     // After sized formats we attempt an unsized format and take
1678     // whatever sizes GL gives us. In that case we query for the size.
1679     GrGLStencilAttachment::Format format = sFmt;
1680     get_stencil_rb_sizes(this->glInterface(), &format);
1681     GrGLStencilAttachment* stencil = new GrGLStencilAttachment(this,
1682                                                                sbDesc,
1683                                                                width,
1684                                                                height,
1685                                                                samples,
1686                                                                format);
1687     return stencil;
1688 }
1689 
1690 ////////////////////////////////////////////////////////////////////////////////
1691 
1692 // GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer
1693 // objects are implemented as client-side-arrays on tile-deferred architectures.
1694 #define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW
1695 
onCreateBuffer(size_t size,GrBufferType intendedType,GrAccessPattern accessPattern,const void * data)1696 GrBuffer* GrGLGpu::onCreateBuffer(size_t size, GrBufferType intendedType,
1697                                   GrAccessPattern accessPattern, const void* data) {
1698     return GrGLBuffer::Create(this, size, intendedType, accessPattern, data);
1699 }
1700 
1701 
onCreateInstancedRenderingAllocator()1702 std::unique_ptr<OpAllocator> GrGLGpu::onCreateInstancedRenderingAllocator() {
1703     return std::unique_ptr<OpAllocator>(new GLOpAllocator(this->caps()));
1704 }
1705 
onCreateInstancedRendering()1706 InstancedRendering* GrGLGpu::onCreateInstancedRendering() {
1707     return new GLInstancedRendering(this);
1708 }
1709 
flushScissor(const GrScissorState & scissorState,const GrGLIRect & rtViewport,GrSurfaceOrigin rtOrigin)1710 void GrGLGpu::flushScissor(const GrScissorState& scissorState,
1711                            const GrGLIRect& rtViewport,
1712                            GrSurfaceOrigin rtOrigin) {
1713     if (scissorState.enabled()) {
1714         GrGLIRect scissor;
1715         scissor.setRelativeTo(rtViewport,
1716                               scissorState.rect().fLeft,
1717                               scissorState.rect().fTop,
1718                               scissorState.rect().width(),
1719                               scissorState.rect().height(),
1720                               rtOrigin);
1721         // if the scissor fully contains the viewport then we fall through and
1722         // disable the scissor test.
1723         if (!scissor.contains(rtViewport)) {
1724             if (fHWScissorSettings.fRect != scissor) {
1725                 scissor.pushToGLScissor(this->glInterface());
1726                 fHWScissorSettings.fRect = scissor;
1727             }
1728             if (kYes_TriState != fHWScissorSettings.fEnabled) {
1729                 GL_CALL(Enable(GR_GL_SCISSOR_TEST));
1730                 fHWScissorSettings.fEnabled = kYes_TriState;
1731             }
1732             return;
1733         }
1734     }
1735 
1736     // See fall through note above
1737     this->disableScissor();
1738 }
1739 
flushWindowRectangles(const GrWindowRectsState & windowState,const GrGLRenderTarget * rt)1740 void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
1741                                     const GrGLRenderTarget* rt) {
1742 #ifndef USE_NSIGHT
1743     typedef GrWindowRectsState::Mode Mode;
1744     SkASSERT(!windowState.enabled() || rt->renderFBOID()); // Window rects can't be used on-screen.
1745     SkASSERT(windowState.numWindows() <= this->caps()->maxWindowRectangles());
1746 
1747     if (!this->caps()->maxWindowRectangles() ||
1748         fHWWindowRectsState.knownEqualTo(rt->origin(), rt->getViewport(), windowState)) {
1749         return;
1750     }
1751 
1752     // This is purely a workaround for a spurious warning generated by gcc. Otherwise the above
1753     // assert would be sufficient. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=5912
1754     int numWindows = SkTMin(windowState.numWindows(), int(GrWindowRectangles::kMaxWindows));
1755     SkASSERT(windowState.numWindows() == numWindows);
1756 
1757     GrGLIRect glwindows[GrWindowRectangles::kMaxWindows];
1758     const SkIRect* skwindows = windowState.windows().data();
1759     for (int i = 0; i < numWindows; ++i) {
1760         glwindows[i].setRelativeTo(rt->getViewport(), skwindows[i], rt->origin());
1761     }
1762 
1763     GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE;
1764     GL_CALL(WindowRectangles(glmode, numWindows, glwindows->asInts()));
1765 
1766     fHWWindowRectsState.set(rt->origin(), rt->getViewport(), windowState);
1767 #endif
1768 }
1769 
disableWindowRectangles()1770 void GrGLGpu::disableWindowRectangles() {
1771 #ifndef USE_NSIGHT
1772     if (!this->caps()->maxWindowRectangles() || fHWWindowRectsState.knownDisabled()) {
1773         return;
1774     }
1775     GL_CALL(WindowRectangles(GR_GL_EXCLUSIVE, 0, nullptr));
1776     fHWWindowRectsState.setDisabled();
1777 #endif
1778 }
1779 
flushMinSampleShading(float minSampleShading)1780 void GrGLGpu::flushMinSampleShading(float minSampleShading) {
1781     if (fHWMinSampleShading != minSampleShading) {
1782         if (minSampleShading > 0.0) {
1783             GL_CALL(Enable(GR_GL_SAMPLE_SHADING));
1784             GL_CALL(MinSampleShading(minSampleShading));
1785         }
1786         else {
1787             GL_CALL(Disable(GR_GL_SAMPLE_SHADING));
1788         }
1789         fHWMinSampleShading = minSampleShading;
1790     }
1791 }
1792 
flushGLState(const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,bool willDrawPoints)1793 bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc,
1794                            bool willDrawPoints) {
1795     sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc, willDrawPoints));
1796     if (!program) {
1797         GrCapsDebugf(this->caps(), "Failed to create program!\n");
1798         return false;
1799     }
1800 
1801     program->generateMipmaps(primProc, pipeline);
1802 
1803     GrXferProcessor::BlendInfo blendInfo;
1804     pipeline.getXferProcessor().getBlendInfo(&blendInfo);
1805 
1806     this->flushColorWrite(blendInfo.fWriteColor);
1807     this->flushMinSampleShading(primProc.getSampleShading());
1808 
1809     GrGLuint programID = program->programID();
1810     if (fHWProgramID != programID) {
1811         GL_CALL(UseProgram(programID));
1812         fHWProgramID = programID;
1813     }
1814 
1815     if (blendInfo.fWriteColor) {
1816         // Swizzle the blend to match what the shader will output.
1817         const GrSwizzle& swizzle = this->caps()->shaderCaps()->configOutputSwizzle(
1818             pipeline.getRenderTarget()->config());
1819         this->flushBlend(blendInfo, swizzle);
1820     }
1821 
1822     program->setData(primProc, pipeline);
1823 
1824     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
1825     GrStencilSettings stencil;
1826     if (pipeline.isStencilEnabled()) {
1827         // TODO: attach stencil and create settings during render target flush.
1828         SkASSERT(glRT->renderTargetPriv().getStencilAttachment());
1829         stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
1830                       glRT->renderTargetPriv().numStencilBits());
1831     }
1832     this->flushStencil(stencil);
1833     this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
1834     this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT);
1835     this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled());
1836 
1837     // This must come after textures are flushed because a texture may need
1838     // to be msaa-resolved (which will modify bound FBO state).
1839     this->flushRenderTarget(glRT, nullptr, pipeline.getDisableOutputConversionToSRGB());
1840 
1841     return true;
1842 }
1843 
setupGeometry(const GrPrimitiveProcessor & primProc,const GrBuffer * indexBuffer,const GrBuffer * vertexBuffer,int baseVertex,const GrBuffer * instanceBuffer,int baseInstance)1844 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
1845                             const GrBuffer* indexBuffer,
1846                             const GrBuffer* vertexBuffer,
1847                             int baseVertex,
1848                             const GrBuffer* instanceBuffer,
1849                             int baseInstance) {
1850     GrGLAttribArrayState* attribState;
1851     if (indexBuffer) {
1852         SkASSERT(indexBuffer && !indexBuffer->isMapped());
1853         attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
1854     } else {
1855         attribState = fHWVertexArrayState.bindInternalVertexArray(this);
1856     }
1857 
1858     struct {
1859         const GrBuffer*   fBuffer;
1860         int               fStride;
1861         size_t            fBufferOffset;
1862     } bindings[2];
1863 
1864     if (int vertexStride = primProc.getVertexStride()) {
1865         SkASSERT(vertexBuffer && !vertexBuffer->isMapped());
1866         bindings[0].fBuffer = vertexBuffer;
1867         bindings[0].fStride = vertexStride;
1868         bindings[0].fBufferOffset = vertexBuffer->baseOffset() + baseVertex * vertexStride;
1869     }
1870     if (int instanceStride = primProc.getInstanceStride()) {
1871         SkASSERT(instanceBuffer && !instanceBuffer->isMapped());
1872         bindings[1].fBuffer = instanceBuffer;
1873         bindings[1].fStride = instanceStride;
1874         bindings[1].fBufferOffset = instanceBuffer->baseOffset() + baseInstance * instanceStride;
1875     }
1876 
1877     int numAttribs = primProc.numAttribs();
1878     attribState->enableVertexArrays(this, numAttribs);
1879 
1880     for (int i = 0; i < numAttribs; ++i) {
1881         using InputRate = GrPrimitiveProcessor::Attribute::InputRate;
1882         const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(i);
1883         const int divisor = InputRate::kPerInstance == attrib.fInputRate ? 1 : 0;
1884         const auto& binding = bindings[divisor];
1885         attribState->set(this, i, binding.fBuffer, attrib.fType, binding.fStride,
1886                          binding.fBufferOffset + attrib.fOffsetInRecord, divisor);
1887     }
1888 }
1889 
bindBuffer(GrBufferType type,const GrBuffer * buffer)1890 GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrBuffer* buffer) {
1891     this->handleDirtyContext();
1892 
1893     // Index buffer state is tied to the vertex array.
1894     if (kIndex_GrBufferType == type) {
1895         this->bindVertexArray(0);
1896     }
1897 
1898     SkASSERT(type >= 0 && type <= kLast_GrBufferType);
1899     auto& bufferState = fHWBufferState[type];
1900 
1901     if (buffer->uniqueID() != bufferState.fBoundBufferUniqueID) {
1902         if (buffer->isCPUBacked()) {
1903             if (!bufferState.fBufferZeroKnownBound) {
1904                 GL_CALL(BindBuffer(bufferState.fGLTarget, 0));
1905             }
1906         } else {
1907             const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(buffer);
1908             GL_CALL(BindBuffer(bufferState.fGLTarget, glBuffer->bufferID()));
1909         }
1910         bufferState.fBufferZeroKnownBound = buffer->isCPUBacked();
1911         bufferState.fBoundBufferUniqueID = buffer->uniqueID();
1912     }
1913 
1914     return bufferState.fGLTarget;
1915 }
1916 
notifyBufferReleased(const GrGLBuffer * buffer)1917 void GrGLGpu::notifyBufferReleased(const GrGLBuffer* buffer) {
1918     if (buffer->hasAttachedToTexture()) {
1919         // Detach this buffer from any textures to ensure the underlying memory is freed.
1920         GrGpuResource::UniqueID uniqueID = buffer->uniqueID();
1921         for (int i = fHWMaxUsedBufferTextureUnit; i >= 0; --i) {
1922             auto& buffTex = fHWBufferTextures[i];
1923             if (uniqueID != buffTex.fAttachedBufferUniqueID) {
1924                 continue;
1925             }
1926             if (i == fHWMaxUsedBufferTextureUnit) {
1927                 --fHWMaxUsedBufferTextureUnit;
1928             }
1929 
1930             this->setTextureUnit(i);
1931             if (!buffTex.fKnownBound) {
1932                 SkASSERT(buffTex.fTextureID);
1933                 GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID));
1934                 buffTex.fKnownBound = true;
1935             }
1936             GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER,
1937                               this->glCaps().configSizedInternalFormat(buffTex.fTexelConfig), 0));
1938         }
1939     }
1940 }
1941 
disableScissor()1942 void GrGLGpu::disableScissor() {
1943     if (kNo_TriState != fHWScissorSettings.fEnabled) {
1944         GL_CALL(Disable(GR_GL_SCISSOR_TEST));
1945         fHWScissorSettings.fEnabled = kNo_TriState;
1946         return;
1947     }
1948 }
1949 
clear(const GrFixedClip & clip,GrColor color,GrRenderTarget * target)1950 void GrGLGpu::clear(const GrFixedClip& clip, GrColor color, GrRenderTarget* target) {
1951     this->handleDirtyContext();
1952 
1953     // parent class should never let us get here with no RT
1954     SkASSERT(target);
1955     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
1956 
1957     this->flushRenderTarget(glRT, clip.scissorEnabled() ? &clip.scissorRect() : nullptr);
1958     this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
1959     this->flushWindowRectangles(clip.windowRectsState(), glRT);
1960 
1961     GrGLfloat r, g, b, a;
1962     static const GrGLfloat scale255 = 1.f / 255.f;
1963     a = GrColorUnpackA(color) * scale255;
1964     GrGLfloat scaleRGB = scale255;
1965     r = GrColorUnpackR(color) * scaleRGB;
1966     g = GrColorUnpackG(color) * scaleRGB;
1967     b = GrColorUnpackB(color) * scaleRGB;
1968 
1969     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
1970     fHWWriteToColor = kYes_TriState;
1971 
1972     if (this->glCaps().clearToBoundaryValuesIsBroken() &&
1973         (1 == r || 0 == r) && (1 == g || 0 == g) && (1 == b || 0 == b) && (1 == a || 0 == a)) {
1974         static const GrGLfloat safeAlpha1 = nextafter(1.f, 2.f);
1975         static const GrGLfloat safeAlpha0 = nextafter(0.f, -1.f);
1976         a = (1 == a) ? safeAlpha1 : safeAlpha0;
1977     }
1978     GL_CALL(ClearColor(r, g, b, a));
1979     GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
1980 }
1981 
clearStencil(GrRenderTarget * target)1982 void GrGLGpu::clearStencil(GrRenderTarget* target) {
1983     if (nullptr == target) {
1984         return;
1985     }
1986     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
1987     this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
1988 
1989     this->disableScissor();
1990     this->disableWindowRectangles();
1991 
1992     GL_CALL(StencilMask(0xffffffff));
1993     GL_CALL(ClearStencil(0));
1994     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
1995     fHWStencilSettings.invalidate();
1996 }
1997 
clearStencilClip(const GrFixedClip & clip,bool insideStencilMask,GrRenderTarget * target)1998 void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
1999                                bool insideStencilMask,
2000                                GrRenderTarget* target) {
2001     SkASSERT(target);
2002     this->handleDirtyContext();
2003 
2004     if (this->glCaps().useDrawToClearStencilClip()) {
2005         this->clearStencilClipAsDraw(clip, insideStencilMask, target);
2006         return;
2007     }
2008 
2009     GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
2010     // this should only be called internally when we know we have a
2011     // stencil buffer.
2012     SkASSERT(sb);
2013     GrGLint stencilBitCount =  sb->bits();
2014 #if 0
2015     SkASSERT(stencilBitCount > 0);
2016     GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
2017 #else
2018     // we could just clear the clip bit but when we go through
2019     // ANGLE a partial stencil mask will cause clears to be
2020     // turned into draws. Our contract on GrOpList says that
2021     // changing the clip between stencil passes may or may not
2022     // zero the client's clip bits. So we just clear the whole thing.
2023     static const GrGLint clipStencilMask  = ~0;
2024 #endif
2025     GrGLint value;
2026     if (insideStencilMask) {
2027         value = (1 << (stencilBitCount - 1));
2028     } else {
2029         value = 0;
2030     }
2031     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
2032     this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
2033 
2034     this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
2035     this->flushWindowRectangles(clip.windowRectsState(), glRT);
2036 
2037     GL_CALL(StencilMask((uint32_t) clipStencilMask));
2038     GL_CALL(ClearStencil(value));
2039     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
2040     fHWStencilSettings.invalidate();
2041 }
2042 
read_pixels_pays_for_y_flip(GrSurfaceOrigin origin,const GrGLCaps & caps,int width,int height,GrPixelConfig config,size_t rowBytes)2043 static bool read_pixels_pays_for_y_flip(GrSurfaceOrigin origin, const GrGLCaps& caps,
2044                                         int width, int height,  GrPixelConfig config,
2045                                         size_t rowBytes) {
2046     // If the surface is already TopLeft, we don't need to flip.
2047     if (kTopLeft_GrSurfaceOrigin == origin) {
2048         return false;
2049     }
2050 
2051     // If the read is really small or smaller than the min texture size, don't force a draw.
2052     static const int kMinSize = 32;
2053     if (width < kMinSize || height < kMinSize) {
2054         return false;
2055     }
2056 
2057     // if GL can do the flip then we'll never pay for it.
2058     if (caps.packFlipYSupport()) {
2059         return false;
2060     }
2061 
2062     // If we have to do memcpy to handle non-trim rowBytes then we
2063     // get the flip for free. Otherwise it costs.
2064     // Note that we're assuming that 0 rowBytes has already been handled and that the width has been
2065     // clipped.
2066     return caps.packRowLengthSupport() || GrBytesPerPixel(config) * width == rowBytes;
2067 }
2068 
readPixelsSupported(GrRenderTarget * target,GrPixelConfig readConfig)2069 bool GrGLGpu::readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig) {
2070 #ifdef SK_BUILD_FOR_MAC
2071     // Chromium may ask us to read back from locked IOSurfaces. Calling the command buffer's
2072     // glGetIntegerv() with GL_IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE causes the command buffer
2073     // to make a call to check the framebuffer status which can hang the driver. So in Mac Chromium
2074     // we always use a temporary surface to test for read pixels support.
2075     // https://www.crbug.com/662802
2076     if (this->glContext().driver() == kChromium_GrGLDriver) {
2077         return this->readPixelsSupported(target->config(), readConfig);
2078     }
2079 #endif
2080     auto bindRenderTarget = [this, target]() -> bool {
2081         this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target), &SkIRect::EmptyIRect());
2082         return true;
2083     };
2084     auto unbindRenderTarget = []{};
2085     auto getIntegerv = [this](GrGLenum query, GrGLint* value) {
2086         GR_GL_GetIntegerv(this->glInterface(), query, value);
2087     };
2088     GrPixelConfig rtConfig = target->config();
2089     return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget,
2090                                               unbindRenderTarget);
2091 }
2092 
readPixelsSupported(GrPixelConfig rtConfig,GrPixelConfig readConfig)2093 bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConfig) {
2094     sk_sp<GrTexture> temp;
2095     auto bindRenderTarget = [this, rtConfig, &temp]() -> bool {
2096         GrTextureDesc desc;
2097         desc.fConfig = rtConfig;
2098         desc.fWidth = desc.fHeight = 16;
2099         if (this->glCaps().isConfigRenderable(rtConfig, false)) {
2100             desc.fFlags = kRenderTarget_GrSurfaceFlag;
2101             temp = this->createTexture(desc, SkBudgeted::kNo);
2102             if (!temp) {
2103                 return false;
2104             }
2105             GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(temp->asRenderTarget());
2106             this->flushRenderTarget(glrt, &SkIRect::EmptyIRect());
2107             return true;
2108         } else if (this->glCaps().canConfigBeFBOColorAttachment(rtConfig)) {
2109             temp = this->createTexture(desc, SkBudgeted::kNo);
2110             if (!temp) {
2111                 return false;
2112             }
2113             GrGLIRect vp;
2114             this->bindSurfaceFBOForPixelOps(temp.get(), GR_GL_FRAMEBUFFER, &vp, kDst_TempFBOTarget);
2115             fHWBoundRenderTargetUniqueID.makeInvalid();
2116             return true;
2117         }
2118         return false;
2119     };
2120     auto unbindRenderTarget = [this, &temp]() {
2121         this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, temp.get());
2122     };
2123     auto getIntegerv = [this](GrGLenum query, GrGLint* value) {
2124         GR_GL_GetIntegerv(this->glInterface(), query, value);
2125     };
2126     return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget,
2127                                               unbindRenderTarget);
2128 }
2129 
readPixelsSupported(GrSurface * surfaceForConfig,GrPixelConfig readConfig)2130 bool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig) {
2131     if (GrRenderTarget* rt = surfaceForConfig->asRenderTarget()) {
2132         return this->readPixelsSupported(rt, readConfig);
2133     } else {
2134         GrPixelConfig config = surfaceForConfig->config();
2135         return this->readPixelsSupported(config, readConfig);
2136     }
2137 }
2138 
requires_srgb_conversion(GrPixelConfig a,GrPixelConfig b)2139 static bool requires_srgb_conversion(GrPixelConfig a, GrPixelConfig b) {
2140     if (GrPixelConfigIsSRGB(a)) {
2141         return !GrPixelConfigIsSRGB(b) && !GrPixelConfigIsAlphaOnly(b);
2142     } else if (GrPixelConfigIsSRGB(b)) {
2143         return !GrPixelConfigIsSRGB(a) && !GrPixelConfigIsAlphaOnly(a);
2144     }
2145     return false;
2146 }
2147 
onGetReadPixelsInfo(GrSurface * srcSurface,int width,int height,size_t rowBytes,GrPixelConfig readConfig,DrawPreference * drawPreference,ReadPixelTempDrawInfo * tempDrawInfo)2148 bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
2149                                   GrPixelConfig readConfig, DrawPreference* drawPreference,
2150                                   ReadPixelTempDrawInfo* tempDrawInfo) {
2151     GrPixelConfig srcConfig = srcSurface->config();
2152 
2153     // These settings we will always want if a temp draw is performed.
2154     tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
2155     tempDrawInfo->fTempSurfaceDesc.fWidth = width;
2156     tempDrawInfo->fTempSurfaceDesc.fHeight = height;
2157     tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
2158     tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
2159     tempDrawInfo->fTempSurfaceFit = this->glCaps().partialFBOReadIsSlow() ? SkBackingFit::kExact
2160                                                                           : SkBackingFit::kApprox;
2161     // For now assume no swizzling, we may change that below.
2162     tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
2163 
2164     // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read
2165     // from will be srcConfig and we will read readConfig pixels from it.
2166     // Note that if we require a draw and return a non-renderable format for the temp surface the
2167     // base class will fail for us.
2168     tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
2169     tempDrawInfo->fReadConfig = readConfig;
2170 
2171     if (requires_srgb_conversion(srcConfig, readConfig)) {
2172         if (!this->readPixelsSupported(readConfig, readConfig)) {
2173             return false;
2174         }
2175         // Draw to do srgb to linear conversion or vice versa.
2176         ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2177         tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
2178         tempDrawInfo->fReadConfig = readConfig;
2179         return true;
2180     }
2181 
2182     if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig &&
2183         this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelConfig)) {
2184         tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig;
2185         tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2186         tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig;
2187         ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2188     } else if (this->glCaps().rgbaToBgraReadbackConversionsAreSlow() &&
2189                GrBytesPerPixel(readConfig) == 4 &&
2190                GrPixelConfigSwapRAndB(readConfig) == srcConfig &&
2191                this->readPixelsSupported(srcSurface, srcConfig)) {
2192         // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa.
2193         // Better to do a draw with a R/B swap and then read as the original config.
2194         tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
2195         tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2196         tempDrawInfo->fReadConfig = srcConfig;
2197         ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2198     } else if (!this->readPixelsSupported(srcSurface, readConfig)) {
2199         if (readConfig == kBGRA_8888_GrPixelConfig &&
2200             this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig) &&
2201             this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPixelConfig)) {
2202             // We're trying to read BGRA but it's not supported. If RGBA is renderable and
2203             // we can read it back, then do a swizzling draw to a RGBA and read it back (which
2204             // will effectively be BGRA).
2205             tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
2206             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2207             tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig;
2208             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2209         } else if (readConfig == kSBGRA_8888_GrPixelConfig &&
2210             this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) &&
2211             this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, kSRGBA_8888_GrPixelConfig)) {
2212             // We're trying to read sBGRA but it's not supported. If sRGBA is renderable and
2213             // we can read it back, then do a swizzling draw to a sRGBA and read it back (which
2214             // will effectively be sBGRA).
2215             tempDrawInfo->fTempSurfaceDesc.fConfig = kSRGBA_8888_GrPixelConfig;
2216             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2217             tempDrawInfo->fReadConfig = kSRGBA_8888_GrPixelConfig;
2218             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2219         } else if (readConfig == kAlpha_8_GrPixelConfig) {
2220             // onReadPixels implements a fallback for cases where we are want to read kAlpha_8,
2221             // it's unsupported, but 32bit RGBA reads are supported.
2222             // Don't attempt to do any srgb conversions since we only care about alpha.
2223             GrPixelConfig cpuTempConfig = kRGBA_8888_GrPixelConfig;
2224             if (GrPixelConfigIsSRGB(srcSurface->config())) {
2225                 cpuTempConfig = kSRGBA_8888_GrPixelConfig;
2226             }
2227             if (!this->readPixelsSupported(srcSurface, cpuTempConfig)) {
2228                 // If we can't read RGBA from the src try to draw to a kRGBA_8888 (or kSRGBA_8888)
2229                 // first and then onReadPixels will read that to a 32bit temporary buffer.
2230                 if (this->glCaps().canConfigBeFBOColorAttachment(cpuTempConfig)) {
2231                     ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2232                     tempDrawInfo->fTempSurfaceDesc.fConfig = cpuTempConfig;
2233                     tempDrawInfo->fReadConfig = kAlpha_8_GrPixelConfig;
2234                 } else {
2235                     return false;
2236                 }
2237             } else {
2238                 SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
2239                 SkASSERT(tempDrawInfo->fReadConfig == kAlpha_8_GrPixelConfig);
2240             }
2241         } else if (this->glCaps().canConfigBeFBOColorAttachment(readConfig) &&
2242                    this->readPixelsSupported(readConfig, readConfig)) {
2243             // Do a draw to convert from the src config to the read config.
2244             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2245             tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
2246             tempDrawInfo->fReadConfig = readConfig;
2247         } else {
2248             return false;
2249         }
2250     }
2251 
2252     if ((srcSurface->asRenderTarget() || this->glCaps().canConfigBeFBOColorAttachment(srcConfig)) &&
2253         read_pixels_pays_for_y_flip(srcSurface->origin(), this->glCaps(), width, height, readConfig,
2254                                     rowBytes)) {
2255         ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2256     }
2257 
2258     return true;
2259 }
2260 
onReadPixels(GrSurface * surface,int left,int top,int width,int height,GrPixelConfig config,void * buffer,size_t rowBytes)2261 bool GrGLGpu::onReadPixels(GrSurface* surface,
2262                            int left, int top,
2263                            int width, int height,
2264                            GrPixelConfig config,
2265                            void* buffer,
2266                            size_t rowBytes) {
2267     SkASSERT(surface);
2268 
2269     GrGLRenderTarget* renderTarget = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
2270     if (!renderTarget && !this->glCaps().canConfigBeFBOColorAttachment(surface->config())) {
2271         return false;
2272     }
2273 
2274     // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
2275     if (requires_srgb_conversion(surface->config(), config)) {
2276         return false;
2277     }
2278 
2279     // We have a special case fallback for reading eight bit alpha. We will read back all four 8
2280     // bit channels as RGBA and then extract A.
2281     if (!this->readPixelsSupported(surface, config)) {
2282         // Don't attempt to do any srgb conversions since we only care about alpha.
2283         GrPixelConfig tempConfig = kRGBA_8888_GrPixelConfig;
2284         if (GrPixelConfigIsSRGB(surface->config())) {
2285             tempConfig = kSRGBA_8888_GrPixelConfig;
2286         }
2287         if (kAlpha_8_GrPixelConfig == config &&
2288             this->readPixelsSupported(surface, tempConfig)) {
2289             std::unique_ptr<uint32_t[]> temp(new uint32_t[width * height * 4]);
2290             if (this->onReadPixels(surface, left, top, width, height, tempConfig, temp.get(),
2291                                    width*4)) {
2292                 uint8_t* dst = reinterpret_cast<uint8_t*>(buffer);
2293                 for (int j = 0; j < height; ++j) {
2294                     for (int i = 0; i < width; ++i) {
2295                         dst[j*rowBytes + i] = (0xFF000000U & temp[j*width+i]) >> 24;
2296                     }
2297                 }
2298                 return true;
2299             }
2300         }
2301         return false;
2302     }
2303 
2304     GrGLenum externalFormat;
2305     GrGLenum externalType;
2306     if (!this->glCaps().getReadPixelsFormat(surface->config(), config, &externalFormat,
2307                                             &externalType)) {
2308         return false;
2309     }
2310     bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
2311 
2312     GrGLIRect glvp;
2313     if (renderTarget) {
2314         // resolve the render target if necessary
2315         switch (renderTarget->getResolveType()) {
2316             case GrGLRenderTarget::kCantResolve_ResolveType:
2317                 return false;
2318             case GrGLRenderTarget::kAutoResolves_ResolveType:
2319                 this->flushRenderTarget(renderTarget, &SkIRect::EmptyIRect());
2320                 break;
2321             case GrGLRenderTarget::kCanResolve_ResolveType:
2322                 this->onResolveRenderTarget(renderTarget);
2323                 // we don't track the state of the READ FBO ID.
2324                 fStats.incRenderTargetBinds();
2325                 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID()));
2326                 break;
2327             default:
2328                 SkFAIL("Unknown resolve type");
2329         }
2330         glvp = renderTarget->getViewport();
2331     } else {
2332         // Use a temporary FBO.
2333         this->bindSurfaceFBOForPixelOps(surface, GR_GL_FRAMEBUFFER, &glvp, kSrc_TempFBOTarget);
2334         fHWBoundRenderTargetUniqueID.makeInvalid();
2335     }
2336 
2337     // the read rect is viewport-relative
2338     GrGLIRect readRect;
2339     readRect.setRelativeTo(glvp, left, top, width, height, surface->origin());
2340 
2341     size_t bytesPerPixel = GrBytesPerPixel(config);
2342     size_t tightRowBytes = bytesPerPixel * width;
2343 
2344     size_t readDstRowBytes = tightRowBytes;
2345     void* readDst = buffer;
2346 
2347     // determine if GL can read using the passed rowBytes or if we need
2348     // a scratch buffer.
2349     SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
2350     if (rowBytes != tightRowBytes) {
2351         if (this->glCaps().packRowLengthSupport() && !(rowBytes % bytesPerPixel)) {
2352             GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH,
2353                                 static_cast<GrGLint>(rowBytes / bytesPerPixel)));
2354             readDstRowBytes = rowBytes;
2355         } else {
2356             scratch.reset(tightRowBytes * height);
2357             readDst = scratch.get();
2358         }
2359     }
2360     if (flipY && this->glCaps().packFlipYSupport()) {
2361         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1));
2362     }
2363     GL_CALL(PixelStorei(GR_GL_PACK_ALIGNMENT, config_alignment(config)));
2364 
2365     GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
2366                        readRect.fWidth, readRect.fHeight,
2367                        externalFormat, externalType, readDst));
2368     if (readDstRowBytes != tightRowBytes) {
2369         SkASSERT(this->glCaps().packRowLengthSupport());
2370         GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
2371     }
2372     if (flipY && this->glCaps().packFlipYSupport()) {
2373         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0));
2374         flipY = false;
2375     }
2376 
2377     // now reverse the order of the rows, since GL's are bottom-to-top, but our
2378     // API presents top-to-bottom. We must preserve the padding contents. Note
2379     // that the above readPixels did not overwrite the padding.
2380     if (readDst == buffer) {
2381         SkASSERT(rowBytes == readDstRowBytes);
2382         if (flipY) {
2383             scratch.reset(tightRowBytes);
2384             void* tmpRow = scratch.get();
2385             // flip y in-place by rows
2386             const int halfY = height >> 1;
2387             char* top = reinterpret_cast<char*>(buffer);
2388             char* bottom = top + (height - 1) * rowBytes;
2389             for (int y = 0; y < halfY; y++) {
2390                 memcpy(tmpRow, top, tightRowBytes);
2391                 memcpy(top, bottom, tightRowBytes);
2392                 memcpy(bottom, tmpRow, tightRowBytes);
2393                 top += rowBytes;
2394                 bottom -= rowBytes;
2395             }
2396         }
2397     } else {
2398         SkASSERT(readDst != buffer);
2399         SkASSERT(rowBytes != tightRowBytes);
2400         // copy from readDst to buffer while flipping y
2401         // const int halfY = height >> 1;
2402         const char* src = reinterpret_cast<const char*>(readDst);
2403         char* dst = reinterpret_cast<char*>(buffer);
2404         if (flipY) {
2405             dst += (height-1) * rowBytes;
2406         }
2407         for (int y = 0; y < height; y++) {
2408             memcpy(dst, src, tightRowBytes);
2409             src += readDstRowBytes;
2410             if (!flipY) {
2411                 dst += rowBytes;
2412             } else {
2413                 dst -= rowBytes;
2414             }
2415         }
2416     }
2417     if (!renderTarget) {
2418         this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, surface);
2419     }
2420     return true;
2421 }
2422 
createCommandBuffer(const GrGpuCommandBuffer::LoadAndStoreInfo & colorInfo,const GrGpuCommandBuffer::LoadAndStoreInfo & stencilInfo)2423 GrGpuCommandBuffer* GrGLGpu::createCommandBuffer(
2424         const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
2425         const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) {
2426     return new GrGLGpuCommandBuffer(this);
2427 }
2428 
flushRenderTarget(GrGLRenderTarget * target,const SkIRect * bounds,bool disableSRGB)2429 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bounds, bool disableSRGB) {
2430     SkASSERT(target);
2431 
2432     GrGpuResource::UniqueID rtID = target->uniqueID();
2433     if (fHWBoundRenderTargetUniqueID != rtID) {
2434         fStats.incRenderTargetBinds();
2435         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
2436 #ifdef SK_DEBUG
2437         // don't do this check in Chromium -- this is causing
2438         // lots of repeated command buffer flushes when the compositor is
2439         // rendering with Ganesh, which is really slow; even too slow for
2440         // Debug mode.
2441         if (kChromium_GrGLDriver != this->glContext().driver()) {
2442             GrGLenum status;
2443             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
2444             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
2445                 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x\n", status);
2446             }
2447         }
2448 #endif
2449         fHWBoundRenderTargetUniqueID = rtID;
2450         this->flushViewport(target->getViewport());
2451     }
2452 
2453     if (this->glCaps().srgbWriteControl()) {
2454         this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !disableSRGB);
2455     }
2456 
2457     this->didWriteToSurface(target, bounds);
2458 }
2459 
flushFramebufferSRGB(bool enable)2460 void GrGLGpu::flushFramebufferSRGB(bool enable) {
2461     if (enable && kYes_TriState != fHWSRGBFramebuffer) {
2462         GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB));
2463         fHWSRGBFramebuffer = kYes_TriState;
2464     } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) {
2465         GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB));
2466         fHWSRGBFramebuffer = kNo_TriState;
2467     }
2468 }
2469 
flushViewport(const GrGLIRect & viewport)2470 void GrGLGpu::flushViewport(const GrGLIRect& viewport) {
2471     if (fHWViewport != viewport) {
2472         viewport.pushToGLViewport(this->glInterface());
2473         fHWViewport = viewport;
2474     }
2475 }
2476 
2477 #define SWAP_PER_DRAW 0
2478 
2479 #if SWAP_PER_DRAW
2480     #if defined(SK_BUILD_FOR_MAC)
2481         #include <AGL/agl.h>
2482     #elif defined(SK_BUILD_FOR_WIN32)
2483         #include <gl/GL.h>
SwapBuf()2484         void SwapBuf() {
2485             DWORD procID = GetCurrentProcessId();
2486             HWND hwnd = GetTopWindow(GetDesktopWindow());
2487             while(hwnd) {
2488                 DWORD wndProcID = 0;
2489                 GetWindowThreadProcessId(hwnd, &wndProcID);
2490                 if(wndProcID == procID) {
2491                     SwapBuffers(GetDC(hwnd));
2492                 }
2493                 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
2494             }
2495          }
2496     #endif
2497 #endif
2498 
draw(const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,const GrMesh meshes[],const GrPipeline::DynamicState dynamicStates[],int meshCount)2499 void GrGLGpu::draw(const GrPipeline& pipeline,
2500                    const GrPrimitiveProcessor& primProc,
2501                    const GrMesh meshes[],
2502                    const GrPipeline::DynamicState dynamicStates[],
2503                    int meshCount) {
2504     this->handleDirtyContext();
2505 
2506     bool hasPoints = false;
2507     for (int i = 0; i < meshCount; ++i) {
2508         if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
2509             hasPoints = true;
2510             break;
2511         }
2512     }
2513     if (!this->flushGLState(pipeline, primProc, hasPoints)) {
2514         return;
2515     }
2516 
2517     for (int i = 0; i < meshCount; ++i) {
2518         if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) {
2519             this->xferBarrier(pipeline.getRenderTarget(), barrierType);
2520         }
2521 
2522         if (dynamicStates) {
2523             if (pipeline.getScissorState().enabled()) {
2524                 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
2525                 this->flushScissor(dynamicStates[i].fScissorRect,
2526                                    glRT->getViewport(), glRT->origin());
2527             }
2528         }
2529         if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
2530             GrIsPrimTypeLines(meshes[i].primitiveType()) &&
2531             !GrIsPrimTypeLines(fLastPrimitiveType)) {
2532             GL_CALL(Enable(GR_GL_CULL_FACE));
2533             GL_CALL(Disable(GR_GL_CULL_FACE));
2534         }
2535         meshes[i].sendToGpu(primProc, this);
2536         fLastPrimitiveType = meshes[i].primitiveType();
2537     }
2538 
2539 #if SWAP_PER_DRAW
2540     glFlush();
2541     #if defined(SK_BUILD_FOR_MAC)
2542         aglSwapBuffers(aglGetCurrentContext());
2543         int set_a_break_pt_here = 9;
2544         aglSwapBuffers(aglGetCurrentContext());
2545     #elif defined(SK_BUILD_FOR_WIN32)
2546         SwapBuf();
2547         int set_a_break_pt_here = 9;
2548         SwapBuf();
2549     #endif
2550 #endif
2551 }
2552 
gr_primitive_type_to_gl_mode(GrPrimitiveType primitiveType)2553 static GrGLenum gr_primitive_type_to_gl_mode(GrPrimitiveType primitiveType) {
2554     switch (primitiveType) {
2555         case GrPrimitiveType::kTriangles:
2556             return GR_GL_TRIANGLES;
2557         case GrPrimitiveType::kTriangleStrip:
2558             return GR_GL_TRIANGLE_STRIP;
2559         case GrPrimitiveType::kTriangleFan:
2560             return GR_GL_TRIANGLE_FAN;
2561         case GrPrimitiveType::kPoints:
2562             return GR_GL_POINTS;
2563         case GrPrimitiveType::kLines:
2564             return GR_GL_LINES;
2565         case GrPrimitiveType::kLineStrip:
2566             return GR_GL_LINE_STRIP;
2567         case GrPrimitiveType::kLinesAdjacency:
2568             return GR_GL_LINES_ADJACENCY;
2569     }
2570     SkFAIL("invalid GrPrimitiveType");
2571     return GR_GL_TRIANGLES;
2572 }
2573 
sendMeshToGpu(const GrPrimitiveProcessor & primProc,GrPrimitiveType primitiveType,const GrBuffer * vertexBuffer,int vertexCount,int baseVertex)2574 void GrGLGpu::sendMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType primitiveType,
2575                             const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) {
2576     const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2577     if (this->glCaps().drawArraysBaseVertexIsBroken()) {
2578         this->setupGeometry(primProc, nullptr, vertexBuffer, baseVertex, nullptr, 0);
2579         GL_CALL(DrawArrays(glPrimType, 0, vertexCount));
2580     } else {
2581         this->setupGeometry(primProc, nullptr, vertexBuffer, 0, nullptr, 0);
2582         GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount));
2583     }
2584     fStats.incNumDraws();
2585 }
2586 
sendIndexedMeshToGpu(const GrPrimitiveProcessor & primProc,GrPrimitiveType primitiveType,const GrBuffer * indexBuffer,int indexCount,int baseIndex,uint16_t minIndexValue,uint16_t maxIndexValue,const GrBuffer * vertexBuffer,int baseVertex)2587 void GrGLGpu::sendIndexedMeshToGpu(const GrPrimitiveProcessor& primProc,
2588                                    GrPrimitiveType primitiveType, const GrBuffer* indexBuffer,
2589                                    int indexCount, int baseIndex, uint16_t minIndexValue,
2590                                    uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
2591                                    int baseVertex) {
2592     const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2593     GrGLvoid* const indices = reinterpret_cast<void*>(indexBuffer->baseOffset() +
2594                                                       sizeof(uint16_t) * baseIndex);
2595 
2596     this->setupGeometry(primProc, indexBuffer, vertexBuffer, baseVertex, nullptr, 0);
2597 
2598     if (this->glCaps().drawRangeElementsSupport()) {
2599         GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount,
2600                                   GR_GL_UNSIGNED_SHORT, indices));
2601     } else {
2602         GL_CALL(DrawElements(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, indices));
2603     }
2604     fStats.incNumDraws();
2605 }
2606 
sendInstancedMeshToGpu(const GrPrimitiveProcessor & primProc,GrPrimitiveType primitiveType,const GrBuffer * vertexBuffer,int vertexCount,int baseVertex,const GrBuffer * instanceBuffer,int instanceCount,int baseInstance)2607 void GrGLGpu::sendInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType
2608                                      primitiveType, const GrBuffer* vertexBuffer,
2609                                      int vertexCount, int baseVertex,
2610                                      const GrBuffer* instanceBuffer, int instanceCount,
2611                                      int baseInstance) {
2612     const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2613     this->setupGeometry(primProc, nullptr, vertexBuffer, 0, instanceBuffer, baseInstance);
2614     GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, instanceCount));
2615     fStats.incNumDraws();
2616 }
2617 
sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor & primProc,GrPrimitiveType primitiveType,const GrBuffer * indexBuffer,int indexCount,int baseIndex,const GrBuffer * vertexBuffer,int baseVertex,const GrBuffer * instanceBuffer,int instanceCount,int baseInstance)2618 void GrGLGpu::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc,
2619                                             GrPrimitiveType primitiveType,
2620                                             const GrBuffer* indexBuffer, int indexCount,
2621                                             int baseIndex, const GrBuffer* vertexBuffer,
2622                                             int baseVertex, const GrBuffer* instanceBuffer,
2623                                             int instanceCount, int baseInstance) {
2624     const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType);
2625     GrGLvoid* indices = reinterpret_cast<void*>(indexBuffer->baseOffset() +
2626                                                 sizeof(uint16_t) * baseIndex);
2627     this->setupGeometry(primProc, indexBuffer, vertexBuffer, baseVertex,
2628                         instanceBuffer, baseInstance);
2629     GL_CALL(DrawElementsInstanced(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, indices,
2630                                   instanceCount));
2631     fStats.incNumDraws();
2632 }
2633 
onResolveRenderTarget(GrRenderTarget * target)2634 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
2635     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
2636     if (rt->needsResolve()) {
2637         // Some extensions automatically resolves the texture when it is read.
2638         if (this->glCaps().usesMSAARenderBuffers()) {
2639             SkASSERT(rt->textureFBOID() != rt->renderFBOID());
2640             fStats.incRenderTargetBinds();
2641             fStats.incRenderTargetBinds();
2642             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
2643             GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
2644             // make sure we go through flushRenderTarget() since we've modified
2645             // the bound DRAW FBO ID.
2646             fHWBoundRenderTargetUniqueID.makeInvalid();
2647             const GrGLIRect& vp = rt->getViewport();
2648             const SkIRect dirtyRect = rt->getResolveRect();
2649 
2650             if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
2651                 // Apple's extension uses the scissor as the blit bounds.
2652                 GrScissorState scissorState;
2653                 scissorState.set(dirtyRect);
2654                 this->flushScissor(scissorState, vp, rt->origin());
2655                 this->disableWindowRectangles();
2656                 GL_CALL(ResolveMultisampleFramebuffer());
2657             } else {
2658                 int l, b, r, t;
2659                 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag &
2660                     this->glCaps().blitFramebufferSupportFlags()) {
2661                     l = 0;
2662                     b = 0;
2663                     r = target->width();
2664                     t = target->height();
2665                 } else {
2666                     GrGLIRect rect;
2667                     rect.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
2668                                        dirtyRect.width(), dirtyRect.height(), target->origin());
2669                     l = rect.fLeft;
2670                     b = rect.fBottom;
2671                     r = rect.fLeft + rect.fWidth;
2672                     t = rect.fBottom + rect.fHeight;
2673                 }
2674 
2675                 // BlitFrameBuffer respects the scissor, so disable it.
2676                 this->disableScissor();
2677                 this->disableWindowRectangles();
2678                 GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t,
2679                                         GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
2680             }
2681         }
2682         rt->flagAsResolved();
2683     }
2684 }
2685 
2686 namespace {
2687 
2688 
gr_to_gl_stencil_op(GrStencilOp op)2689 GrGLenum gr_to_gl_stencil_op(GrStencilOp op) {
2690     static const GrGLenum gTable[kGrStencilOpCount] = {
2691         GR_GL_KEEP,        // kKeep
2692         GR_GL_ZERO,        // kZero
2693         GR_GL_REPLACE,     // kReplace
2694         GR_GL_INVERT,      // kInvert
2695         GR_GL_INCR_WRAP,   // kIncWrap
2696         GR_GL_DECR_WRAP,   // kDecWrap
2697         GR_GL_INCR,        // kIncClamp
2698         GR_GL_DECR,        // kDecClamp
2699     };
2700     GR_STATIC_ASSERT(0 == (int)GrStencilOp::kKeep);
2701     GR_STATIC_ASSERT(1 == (int)GrStencilOp::kZero);
2702     GR_STATIC_ASSERT(2 == (int)GrStencilOp::kReplace);
2703     GR_STATIC_ASSERT(3 == (int)GrStencilOp::kInvert);
2704     GR_STATIC_ASSERT(4 == (int)GrStencilOp::kIncWrap);
2705     GR_STATIC_ASSERT(5 == (int)GrStencilOp::kDecWrap);
2706     GR_STATIC_ASSERT(6 == (int)GrStencilOp::kIncClamp);
2707     GR_STATIC_ASSERT(7 == (int)GrStencilOp::kDecClamp);
2708     SkASSERT(op < (GrStencilOp)kGrStencilOpCount);
2709     return gTable[(int)op];
2710 }
2711 
set_gl_stencil(const GrGLInterface * gl,const GrStencilSettings::Face & face,GrGLenum glFace)2712 void set_gl_stencil(const GrGLInterface* gl,
2713                     const GrStencilSettings::Face& face,
2714                     GrGLenum glFace) {
2715     GrGLenum glFunc = GrToGLStencilFunc(face.fTest);
2716     GrGLenum glFailOp = gr_to_gl_stencil_op(face.fFailOp);
2717     GrGLenum glPassOp = gr_to_gl_stencil_op(face.fPassOp);
2718 
2719     GrGLint ref = face.fRef;
2720     GrGLint mask = face.fTestMask;
2721     GrGLint writeMask = face.fWriteMask;
2722 
2723     if (GR_GL_FRONT_AND_BACK == glFace) {
2724         // we call the combined func just in case separate stencil is not
2725         // supported.
2726         GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask));
2727         GR_GL_CALL(gl, StencilMask(writeMask));
2728         GR_GL_CALL(gl, StencilOp(glFailOp, GR_GL_KEEP, glPassOp));
2729     } else {
2730         GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask));
2731         GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask));
2732         GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, GR_GL_KEEP, glPassOp));
2733     }
2734 }
2735 }
2736 
flushStencil(const GrStencilSettings & stencilSettings)2737 void GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings) {
2738     if (stencilSettings.isDisabled()) {
2739         this->disableStencil();
2740     } else if (fHWStencilSettings != stencilSettings) {
2741         if (kYes_TriState != fHWStencilTestEnabled) {
2742             GL_CALL(Enable(GR_GL_STENCIL_TEST));
2743 
2744             fHWStencilTestEnabled = kYes_TriState;
2745         }
2746         if (stencilSettings.isTwoSided()) {
2747             set_gl_stencil(this->glInterface(),
2748                            stencilSettings.front(),
2749                            GR_GL_FRONT);
2750             set_gl_stencil(this->glInterface(),
2751                            stencilSettings.back(),
2752                            GR_GL_BACK);
2753         } else {
2754             set_gl_stencil(this->glInterface(),
2755                            stencilSettings.front(),
2756                            GR_GL_FRONT_AND_BACK);
2757         }
2758         fHWStencilSettings = stencilSettings;
2759     }
2760 }
2761 
disableStencil()2762 void GrGLGpu::disableStencil() {
2763     if (kNo_TriState != fHWStencilTestEnabled) {
2764         GL_CALL(Disable(GR_GL_STENCIL_TEST));
2765 
2766         fHWStencilTestEnabled = kNo_TriState;
2767         fHWStencilSettings.invalidate();
2768     }
2769 }
2770 
flushHWAAState(GrRenderTarget * rt,bool useHWAA,bool stencilEnabled)2771 void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled) {
2772     // rt is only optional if useHWAA is false.
2773     SkASSERT(rt || !useHWAA);
2774     SkASSERT(!useHWAA || rt->isStencilBufferMultisampled());
2775 
2776     if (this->caps()->multisampleDisableSupport()) {
2777         if (useHWAA) {
2778             if (kYes_TriState != fMSAAEnabled) {
2779                 GL_CALL(Enable(GR_GL_MULTISAMPLE));
2780                 fMSAAEnabled = kYes_TriState;
2781             }
2782         } else {
2783             if (kNo_TriState != fMSAAEnabled) {
2784                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
2785                 fMSAAEnabled = kNo_TriState;
2786             }
2787         }
2788     }
2789 
2790     if (0 != this->caps()->maxRasterSamples()) {
2791         if (useHWAA && GrFSAAType::kMixedSamples == rt->fsaaType() && !stencilEnabled) {
2792             // Since stencil is disabled and we want more samples than are in the color buffer, we
2793             // need to tell the rasterizer explicitly how many to run.
2794             if (kYes_TriState != fHWRasterMultisampleEnabled) {
2795                 GL_CALL(Enable(GR_GL_RASTER_MULTISAMPLE));
2796                 fHWRasterMultisampleEnabled = kYes_TriState;
2797             }
2798             if (rt->numStencilSamples() != fHWNumRasterSamples) {
2799                 SkASSERT(rt->numStencilSamples() <= this->caps()->maxRasterSamples());
2800                 GL_CALL(RasterSamples(rt->numStencilSamples(), GR_GL_TRUE));
2801                 fHWNumRasterSamples = rt->numStencilSamples();
2802             }
2803         } else {
2804             if (kNo_TriState != fHWRasterMultisampleEnabled) {
2805                 GL_CALL(Disable(GR_GL_RASTER_MULTISAMPLE));
2806                 fHWRasterMultisampleEnabled = kNo_TriState;
2807             }
2808         }
2809     } else {
2810         SkASSERT(!useHWAA || GrFSAAType::kMixedSamples != rt->fsaaType() || stencilEnabled);
2811     }
2812 }
2813 
flushBlend(const GrXferProcessor::BlendInfo & blendInfo,const GrSwizzle & swizzle)2814 void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) {
2815     // Any optimization to disable blending should have already been applied and
2816     // tweaked the equation to "add" or "subtract", and the coeffs to (1, 0).
2817 
2818     GrBlendEquation equation = blendInfo.fEquation;
2819     GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
2820     GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
2821     bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) &&
2822                     kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
2823     if (blendOff) {
2824         if (kNo_TriState != fHWBlendState.fEnabled) {
2825             GL_CALL(Disable(GR_GL_BLEND));
2826 
2827             // Workaround for the ARM KHR_blend_equation_advanced blacklist issue
2828             // https://code.google.com/p/skia/issues/detail?id=3943
2829             if (kARM_GrGLVendor == this->ctxInfo().vendor() &&
2830                 GrBlendEquationIsAdvanced(fHWBlendState.fEquation)) {
2831                 SkASSERT(this->caps()->advancedBlendEquationSupport());
2832                 // Set to any basic blending equation.
2833                 GrBlendEquation blend_equation = kAdd_GrBlendEquation;
2834                 GL_CALL(BlendEquation(gXfermodeEquation2Blend[blend_equation]));
2835                 fHWBlendState.fEquation = blend_equation;
2836             }
2837 
2838             fHWBlendState.fEnabled = kNo_TriState;
2839         }
2840         return;
2841     }
2842 
2843     if (kYes_TriState != fHWBlendState.fEnabled) {
2844         GL_CALL(Enable(GR_GL_BLEND));
2845 
2846         fHWBlendState.fEnabled = kYes_TriState;
2847     }
2848 
2849     if (fHWBlendState.fEquation != equation) {
2850         GL_CALL(BlendEquation(gXfermodeEquation2Blend[equation]));
2851         fHWBlendState.fEquation = equation;
2852     }
2853 
2854     if (GrBlendEquationIsAdvanced(equation)) {
2855         SkASSERT(this->caps()->advancedBlendEquationSupport());
2856         // Advanced equations have no other blend state.
2857         return;
2858     }
2859 
2860     if (fHWBlendState.fSrcCoeff != srcCoeff || fHWBlendState.fDstCoeff != dstCoeff) {
2861         GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
2862                           gXfermodeCoeff2Blend[dstCoeff]));
2863         fHWBlendState.fSrcCoeff = srcCoeff;
2864         fHWBlendState.fDstCoeff = dstCoeff;
2865     }
2866 
2867     if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff))) {
2868         GrColor blendConst = blendInfo.fBlendConstant;
2869         blendConst = swizzle.applyTo(blendConst);
2870         if (!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst) {
2871             GrGLfloat c[4];
2872             GrColorToRGBAFloat(blendConst, c);
2873             GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
2874             fHWBlendState.fConstColor = blendConst;
2875             fHWBlendState.fConstColorValid = true;
2876         }
2877     }
2878 }
2879 
tile_to_gl_wrap(SkShader::TileMode tm)2880 static inline GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) {
2881     static const GrGLenum gWrapModes[] = {
2882         GR_GL_CLAMP_TO_EDGE,
2883         GR_GL_REPEAT,
2884         GR_GL_MIRRORED_REPEAT
2885     };
2886     GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes));
2887     GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode);
2888     GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode);
2889     GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode);
2890     return gWrapModes[tm];
2891 }
2892 
get_component_enum_from_char(char component)2893 static GrGLenum get_component_enum_from_char(char component) {
2894     switch (component) {
2895         case 'r':
2896            return GR_GL_RED;
2897         case 'g':
2898            return GR_GL_GREEN;
2899         case 'b':
2900            return GR_GL_BLUE;
2901         case 'a':
2902            return GR_GL_ALPHA;
2903         default:
2904             SkFAIL("Unsupported component");
2905             return 0;
2906     }
2907 }
2908 
2909 /** If texture swizzling is available using tex parameters then it is preferred over mangling
2910   the generated shader code. This potentially allows greater reuse of cached shaders. */
get_tex_param_swizzle(GrPixelConfig config,const GrGLCaps & caps,GrGLenum * glSwizzle)2911 static void get_tex_param_swizzle(GrPixelConfig config,
2912                                   const GrGLCaps& caps,
2913                                   GrGLenum* glSwizzle) {
2914     const GrSwizzle& swizzle = caps.configSwizzle(config);
2915     for (int i = 0; i < 4; ++i) {
2916         glSwizzle[i] = get_component_enum_from_char(swizzle.c_str()[i]);
2917     }
2918 }
2919 
bindTexture(int unitIdx,const GrSamplerParams & params,bool allowSRGBInputs,GrGLTexture * texture)2920 void GrGLGpu::bindTexture(int unitIdx, const GrSamplerParams& params, bool allowSRGBInputs,
2921                           GrGLTexture* texture) {
2922     SkASSERT(texture);
2923 
2924 #ifdef SK_DEBUG
2925     if (!this->caps()->npotTextureTileSupport()) {
2926         const bool tileX = SkShader::kClamp_TileMode != params.getTileModeX();
2927         const bool tileY = SkShader::kClamp_TileMode != params.getTileModeY();
2928         if (tileX || tileY) {
2929             const int w = texture->width();
2930             const int h = texture->height();
2931             SkASSERT(SkIsPow2(w) && SkIsPow2(h));
2932         }
2933     }
2934 #endif
2935 
2936     // If we created a rt/tex and rendered to it without using a texture and now we're texturing
2937     // from the rt it will still be the last bound texture, but it needs resolving. So keep this
2938     // out of the "last != next" check.
2939     GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget());
2940     if (texRT) {
2941         this->onResolveRenderTarget(texRT);
2942     }
2943 
2944     GrGpuResource::UniqueID textureID = texture->uniqueID();
2945     GrGLenum target = texture->target();
2946     if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) {
2947         this->setTextureUnit(unitIdx);
2948         GL_CALL(BindTexture(target, texture->textureID()));
2949         fHWBoundTextureUniqueIDs[unitIdx] = textureID;
2950     }
2951 
2952     ResetTimestamp timestamp;
2953     const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&timestamp);
2954     bool setAll = timestamp < this->getResetTimestamp();
2955     GrGLTexture::TexParams newTexParams;
2956 
2957     static GrGLenum glMinFilterModes[] = {
2958         GR_GL_NEAREST,
2959         GR_GL_LINEAR,
2960         GR_GL_LINEAR_MIPMAP_LINEAR
2961     };
2962     static GrGLenum glMagFilterModes[] = {
2963         GR_GL_NEAREST,
2964         GR_GL_LINEAR,
2965         GR_GL_LINEAR
2966     };
2967     GrSamplerParams::FilterMode filterMode = params.filterMode();
2968 
2969     if (GrSamplerParams::kMipMap_FilterMode == filterMode) {
2970         if (!this->caps()->mipMapSupport()) {
2971             filterMode = GrSamplerParams::kBilerp_FilterMode;
2972         }
2973     }
2974 
2975     newTexParams.fMinFilter = glMinFilterModes[filterMode];
2976     newTexParams.fMagFilter = glMagFilterModes[filterMode];
2977 
2978     if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) {
2979         newTexParams.fSRGBDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT;
2980         if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) {
2981             this->setTextureUnit(unitIdx);
2982             GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexParams.fSRGBDecode));
2983         }
2984     }
2985 
2986 #ifdef SK_DEBUG
2987     // We were supposed to ensure MipMaps were up-to-date and built correctly before getting here.
2988     if (GrSamplerParams::kMipMap_FilterMode == filterMode) {
2989         SkASSERT(!texture->texturePriv().mipMapsAreDirty());
2990         if (GrPixelConfigIsSRGB(texture->config())) {
2991             SkDestinationSurfaceColorMode colorMode = allowSRGBInputs
2992                 ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
2993                 : SkDestinationSurfaceColorMode::kLegacy;
2994             SkASSERT(texture->texturePriv().mipColorMode() == colorMode);
2995         }
2996     }
2997 #endif
2998 
2999     newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel();
3000 
3001     newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
3002     newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
3003     get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizzleRGBA);
3004     if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
3005         this->setTextureUnit(unitIdx);
3006         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMagFilter));
3007     }
3008     if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) {
3009         this->setTextureUnit(unitIdx);
3010         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMinFilter));
3011     }
3012     if (setAll || newTexParams.fMaxMipMapLevel != oldTexParams.fMaxMipMapLevel) {
3013         // These are not supported in ES2 contexts
3014         if (this->glCaps().mipMapLevelAndLodControlSupport()) {
3015             if (newTexParams.fMaxMipMapLevel != 0) {
3016                 this->setTextureUnit(unitIdx);
3017                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0));
3018                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0));
3019                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LOD,
3020                                       newTexParams.fMaxMipMapLevel));
3021                 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL,
3022                                       newTexParams.fMaxMipMapLevel));
3023             }
3024         }
3025     }
3026     if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
3027         this->setTextureUnit(unitIdx);
3028         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS));
3029     }
3030     if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
3031         this->setTextureUnit(unitIdx);
3032         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT));
3033     }
3034     if (this->glCaps().textureSwizzleSupport() &&
3035         (setAll || memcmp(newTexParams.fSwizzleRGBA,
3036                           oldTexParams.fSwizzleRGBA,
3037                           sizeof(newTexParams.fSwizzleRGBA)))) {
3038         this->setTextureSwizzle(unitIdx, target, newTexParams.fSwizzleRGBA);
3039     }
3040     texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
3041 }
3042 
bindTexelBuffer(int unitIdx,GrPixelConfig texelConfig,GrGLBuffer * buffer)3043 void GrGLGpu::bindTexelBuffer(int unitIdx, GrPixelConfig texelConfig, GrGLBuffer* buffer) {
3044     SkASSERT(this->glCaps().canUseConfigWithTexelBuffer(texelConfig));
3045     SkASSERT(unitIdx >= 0 && unitIdx < fHWBufferTextures.count());
3046 
3047     BufferTexture& buffTex = fHWBufferTextures[unitIdx];
3048 
3049     if (!buffTex.fKnownBound) {
3050         if (!buffTex.fTextureID) {
3051             GL_CALL(GenTextures(1, &buffTex.fTextureID));
3052             if (!buffTex.fTextureID) {
3053                 return;
3054             }
3055         }
3056 
3057         this->setTextureUnit(unitIdx);
3058         GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID));
3059 
3060         buffTex.fKnownBound = true;
3061     }
3062 
3063     if (buffer->uniqueID() != buffTex.fAttachedBufferUniqueID ||
3064         buffTex.fTexelConfig != texelConfig) {
3065 
3066         this->setTextureUnit(unitIdx);
3067         GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER,
3068                           this->glCaps().configSizedInternalFormat(texelConfig),
3069                           buffer->bufferID()));
3070 
3071         buffTex.fTexelConfig = texelConfig;
3072         buffTex.fAttachedBufferUniqueID = buffer->uniqueID();
3073 
3074         if (this->glCaps().textureSwizzleSupport() &&
3075             this->glCaps().configSwizzle(texelConfig) != buffTex.fSwizzle) {
3076             GrGLenum glSwizzle[4];
3077             get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle);
3078             this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle);
3079             buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig);
3080         }
3081 
3082         buffer->setHasAttachedToTexture();
3083         fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUnit);
3084     }
3085 }
3086 
bindImageStorage(int unitIdx,GrIOType ioType,GrGLTexture * texture)3087 void GrGLGpu::bindImageStorage(int unitIdx, GrIOType ioType, GrGLTexture *texture) {
3088     SkASSERT(texture);
3089     if (texture->uniqueID() != fHWBoundImageStorages[unitIdx].fTextureUniqueID ||
3090         ioType != fHWBoundImageStorages[unitIdx].fIOType) {
3091         GrGLenum access = GR_GL_READ_ONLY;
3092         switch (ioType) {
3093             case kRead_GrIOType:
3094                 access = GR_GL_READ_ONLY;
3095                 break;
3096             case kWrite_GrIOType:
3097                 access = GR_GL_WRITE_ONLY;
3098                 break;
3099             case kRW_GrIOType:
3100                 access = GR_GL_READ_WRITE;
3101                 break;
3102         }
3103         GrGLenum format = this->glCaps().getImageFormat(texture->config());
3104         GL_CALL(BindImageTexture(unitIdx, texture->textureID(), 0, GR_GL_FALSE, 0, access, format));
3105     }
3106 }
3107 
generateMipmaps(const GrSamplerParams & params,bool allowSRGBInputs,GrGLTexture * texture)3108 void GrGLGpu::generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs,
3109                               GrGLTexture* texture) {
3110     SkASSERT(texture);
3111 
3112     // First, figure out if we need mips for this texture at all:
3113     GrSamplerParams::FilterMode filterMode = params.filterMode();
3114 
3115     if (GrSamplerParams::kMipMap_FilterMode == filterMode) {
3116         if (!this->caps()->mipMapSupport()) {
3117             filterMode = GrSamplerParams::kBilerp_FilterMode;
3118         }
3119     }
3120 
3121     if (GrSamplerParams::kMipMap_FilterMode != filterMode) {
3122         return;
3123     }
3124 
3125     // If this is an sRGB texture and the mips were previously built the "other" way
3126     // (gamma-correct vs. not), then we need to rebuild them. We don't need to check for
3127     // srgbSupport - we'll *never* get an sRGB pixel config if we don't support it.
3128     SkDestinationSurfaceColorMode colorMode = allowSRGBInputs
3129         ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
3130         : SkDestinationSurfaceColorMode::kLegacy;
3131     if (GrPixelConfigIsSRGB(texture->config()) &&
3132         colorMode != texture->texturePriv().mipColorMode()) {
3133         texture->texturePriv().dirtyMipMaps(true);
3134     }
3135 
3136     // If the mips aren't dirty, we're done:
3137     if (!texture->texturePriv().mipMapsAreDirty()) {
3138         return;
3139     }
3140 
3141     // If we created a rt/tex and rendered to it without using a texture and now we're texturing
3142     // from the rt it will still be the last bound texture, but it needs resolving.
3143     GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget());
3144     if (texRT) {
3145         this->onResolveRenderTarget(texRT);
3146     }
3147 
3148     GrGLenum target = texture->target();
3149     this->setScratchTextureUnit();
3150     GL_CALL(BindTexture(target, texture->textureID()));
3151 
3152     // Configure sRGB decode, if necessary. This state is the only thing needed for the driver
3153     // call (glGenerateMipmap) to work correctly. Our manual method dirties other state, too.
3154     if (this->glCaps().srgbDecodeDisableSupport() && GrPixelConfigIsSRGB(texture->config())) {
3155         GrGLenum srgbDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT;
3156         // Command buffer's sRGB decode extension doesn't influence mipmap generation correctly.
3157         // If we set this to skip_decode, it appears to suppress sRGB -> Linear for each downsample,
3158         // but not the Linear -> sRGB when writing the next level. The result is that mip-chains
3159         // get progressively brighter as you go down. Forcing this to 'decode' gives predictable
3160         // (and only slightly incorrect) results. See crbug.com/655247 (~comment 28)
3161         if (!this->glCaps().srgbDecodeDisableAffectsMipmaps()) {
3162             srgbDecode = GR_GL_DECODE_EXT;
3163         }
3164         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, srgbDecode));
3165     }
3166 
3167     // Either do manual mipmap generation or (if that fails), just rely on the driver:
3168     if (!this->generateMipmap(texture, allowSRGBInputs)) {
3169         GL_CALL(GenerateMipmap(target));
3170     }
3171 
3172     texture->texturePriv().dirtyMipMaps(false);
3173     texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount(
3174         texture->width(), texture->height()));
3175     texture->texturePriv().setMipColorMode(colorMode);
3176 
3177     // We have potentially set lots of state on the texture. Easiest to dirty it all:
3178     texture->textureParamsModified();
3179 }
3180 
setTextureSwizzle(int unitIdx,GrGLenum target,const GrGLenum swizzle[])3181 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]) {
3182     this->setTextureUnit(unitIdx);
3183     if (this->glStandard() == kGLES_GrGLStandard) {
3184         // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
3185         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
3186         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
3187         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
3188         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
3189     } else {
3190         GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint));
3191         GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA,
3192                                reinterpret_cast<const GrGLint*>(swizzle)));
3193     }
3194 }
3195 
flushColorWrite(bool writeColor)3196 void GrGLGpu::flushColorWrite(bool writeColor) {
3197     if (!writeColor) {
3198         if (kNo_TriState != fHWWriteToColor) {
3199             GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
3200                               GR_GL_FALSE, GR_GL_FALSE));
3201             fHWWriteToColor = kNo_TriState;
3202         }
3203     } else {
3204         if (kYes_TriState != fHWWriteToColor) {
3205             GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
3206             fHWWriteToColor = kYes_TriState;
3207         }
3208     }
3209 }
3210 
setTextureUnit(int unit)3211 void GrGLGpu::setTextureUnit(int unit) {
3212     SkASSERT(unit >= 0 && unit < fHWBoundTextureUniqueIDs.count());
3213     if (unit != fHWActiveTextureUnitIdx) {
3214         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
3215         fHWActiveTextureUnitIdx = unit;
3216     }
3217 }
3218 
setScratchTextureUnit()3219 void GrGLGpu::setScratchTextureUnit() {
3220     // Bind the last texture unit since it is the least likely to be used by GrGLProgram.
3221     int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1;
3222     if (lastUnitIdx != fHWActiveTextureUnitIdx) {
3223         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx));
3224         fHWActiveTextureUnitIdx = lastUnitIdx;
3225     }
3226     // clear out the this field so that if a program does use this unit it will rebind the correct
3227     // texture.
3228     fHWBoundTextureUniqueIDs[lastUnitIdx].makeInvalid();
3229 }
3230 
3231 // Determines whether glBlitFramebuffer could be used between src and dst by onCopySurface.
can_blit_framebuffer_for_copy_surface(const GrSurface * dst,const GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint,const GrGLGpu * gpu)3232 static inline bool can_blit_framebuffer_for_copy_surface(const GrSurface* dst,
3233                                                          const GrSurface* src,
3234                                                          const SkIRect& srcRect,
3235                                                          const SkIPoint& dstPoint,
3236                                                          const GrGLGpu* gpu) {
3237     auto blitFramebufferFlags = gpu->glCaps().blitFramebufferSupportFlags();
3238     if (!gpu->glCaps().canConfigBeFBOColorAttachment(dst->config()) ||
3239         !gpu->glCaps().canConfigBeFBOColorAttachment(src->config())) {
3240         return false;
3241     }
3242     // Blits are not allowed between int color buffers and float/fixed color buffers. GrGpu should
3243     // have filtered such cases out.
3244     SkASSERT(GrPixelConfigIsSint(dst->config()) == GrPixelConfigIsSint(src->config()));
3245     const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
3246     const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(dst->asTexture());
3247     const GrRenderTarget* dstRT = dst->asRenderTarget();
3248     const GrRenderTarget* srcRT = src->asRenderTarget();
3249     if (dstTex && dstTex->target() != GR_GL_TEXTURE_2D) {
3250         return false;
3251     }
3252     if (srcTex && srcTex->target() != GR_GL_TEXTURE_2D) {
3253         return false;
3254     }
3255     if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
3256         return false;
3257     }
3258     if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
3259         // We would mirror to compensate for origin changes. Note that copySurface is
3260         // specified such that the src and dst rects are the same.
3261         if (dst->origin() != src->origin()) {
3262             return false;
3263         }
3264     }
3265     if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
3266         if (srcRT && srcRT->numColorSamples()) {
3267             if (dstRT && !dstRT->numColorSamples()) {
3268                 return false;
3269             }
3270             if (SkRect::Make(srcRect) != srcRT->getBoundsRect()) {
3271                 return false;
3272             }
3273         }
3274     }
3275     if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
3276         if (dstRT && dstRT->numColorSamples() > 0) {
3277             return false;
3278         }
3279     }
3280     if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
3281         if (dst->config() != src->config()) {
3282             return false;
3283         }
3284     } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3285         const GrRenderTarget* srcRT = src->asRenderTarget();
3286         if (srcRT && srcRT->numColorSamples() && dst->config() != src->config()) {
3287             return false;
3288         }
3289     }
3290     if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3291         if (srcRT && srcRT->numColorSamples()) {
3292             if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
3293                 return false;
3294             }
3295             if (dst->origin() != src->origin()) {
3296                 return false;
3297             }
3298         }
3299     }
3300     return true;
3301 }
3302 
can_copy_texsubimage(const GrSurface * dst,const GrSurface * src,const GrGLGpu * gpu)3303 static inline bool can_copy_texsubimage(const GrSurface* dst,
3304                                         const GrSurface* src,
3305                                         const GrGLGpu* gpu) {
3306     // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3307     // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
3308     // many drivers would allow it to work, but ANGLE does not.
3309     if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalFormat() &&
3310         (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig == src->config())) {
3311         return false;
3312     }
3313     const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget());
3314     // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer)
3315     // then we don't want to copy to the texture but to the MSAA buffer.
3316     if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) {
3317         return false;
3318     }
3319     const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
3320     // If the src is multisampled (and uses an extension where there is a separate MSAA
3321     // renderbuffer) then it is an invalid operation to call CopyTexSubImage
3322     if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
3323         return false;
3324     }
3325 
3326     const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
3327     // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
3328     // texture.
3329     if (!dstTex) {
3330         return false;
3331     }
3332 
3333     const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture());
3334 
3335     // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
3336     // is required.
3337     if (gpu->glCaps().canConfigBeFBOColorAttachment(src->config()) &&
3338         (!srcTex || srcTex->target() == GR_GL_TEXTURE_2D) && dstTex->target() == GR_GL_TEXTURE_2D &&
3339         dst->origin() == src->origin()) {
3340         return true;
3341     } else {
3342         return false;
3343     }
3344 }
3345 
3346 // If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
3347 // relative to is output.
bindSurfaceFBOForPixelOps(GrSurface * surface,GrGLenum fboTarget,GrGLIRect * viewport,TempFBOTarget tempFBOTarget)3348 void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
3349                                         TempFBOTarget tempFBOTarget) {
3350     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
3351     if (!rt) {
3352         SkASSERT(surface->asTexture());
3353         GrGLTexture* texture = static_cast<GrGLTexture*>(surface->asTexture());
3354         GrGLuint texID = texture->textureID();
3355         GrGLenum target = texture->target();
3356         GrGLuint* tempFBOID;
3357         tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTempDstFBOID;
3358 
3359         if (0 == *tempFBOID) {
3360             GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID));
3361         }
3362 
3363         fStats.incRenderTargetBinds();
3364         GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID));
3365         GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
3366                                                              GR_GL_COLOR_ATTACHMENT0,
3367                                                              target,
3368                                                              texID,
3369                                                              0));
3370         texture->baseLevelWasBoundToFBO();
3371         viewport->fLeft = 0;
3372         viewport->fBottom = 0;
3373         viewport->fWidth = surface->width();
3374         viewport->fHeight = surface->height();
3375     } else {
3376         fStats.incRenderTargetBinds();
3377         GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
3378         *viewport = rt->getViewport();
3379     }
3380 }
3381 
unbindTextureFBOForPixelOps(GrGLenum fboTarget,GrSurface * surface)3382 void GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface) {
3383     // bindSurfaceFBOForPixelOps temporarily binds textures that are not render targets to
3384     if (!surface->asRenderTarget()) {
3385         SkASSERT(surface->asTexture());
3386         GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())->target();
3387         GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
3388                                                              GR_GL_COLOR_ATTACHMENT0,
3389                                                              textureTarget,
3390                                                              0,
3391                                                              0));
3392     }
3393 }
3394 
onCopySurface(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3395 bool GrGLGpu::onCopySurface(GrSurface* dst,
3396                             GrSurface* src,
3397                             const SkIRect& srcRect,
3398                             const SkIPoint& dstPoint) {
3399     // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
3400     // swizzle.
3401     if (this->caps()->shaderCaps()->configOutputSwizzle(src->config()) !=
3402         this->caps()->shaderCaps()->configOutputSwizzle(dst->config())) {
3403         return false;
3404     }
3405     // Don't prefer copying as a draw if the dst doesn't already have a FBO object.
3406     bool preferCopy = SkToBool(dst->asRenderTarget());
3407     if (preferCopy && src->asTexture()) {
3408         if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
3409             return true;
3410         }
3411     }
3412 
3413     if (can_copy_texsubimage(dst, src, this)) {
3414         this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
3415         return true;
3416     }
3417 
3418     if (can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this)) {
3419         return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
3420     }
3421 
3422     if (!preferCopy && src->asTexture()) {
3423         if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
3424             return true;
3425         }
3426     }
3427 
3428     return false;
3429 }
3430 
createCopyProgram(GrTexture * srcTex)3431 bool GrGLGpu::createCopyProgram(GrTexture* srcTex) {
3432     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia"), "GrGLGpu::createCopyProgram()");
3433 
3434     int progIdx = TextureToCopyProgramIdx(srcTex);
3435     const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
3436     GrSLType samplerType = srcTex->texturePriv().samplerType();
3437 
3438     if (!fCopyProgramArrayBuffer) {
3439         static const GrGLfloat vdata[] = {
3440             0, 0,
3441             0, 1,
3442             1, 0,
3443             1, 1
3444         };
3445         fCopyProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType,
3446                                                          kStatic_GrAccessPattern, vdata));
3447     }
3448     if (!fCopyProgramArrayBuffer) {
3449         return false;
3450     }
3451 
3452     SkASSERT(!fCopyPrograms[progIdx].fProgram);
3453     GL_CALL_RET(fCopyPrograms[progIdx].fProgram, CreateProgram());
3454     if (!fCopyPrograms[progIdx].fProgram) {
3455         return false;
3456     }
3457 
3458     const char* version = shaderCaps->versionDeclString();
3459     GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
3460     GrShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
3461                                GrShaderVar::kUniform_TypeModifier);
3462     GrShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
3463     GrShaderVar uTexture("u_texture", samplerType, GrShaderVar::kUniform_TypeModifier);
3464     GrShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier);
3465     GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
3466 
3467     SkString vshaderTxt(version);
3468     if (shaderCaps->noperspectiveInterpolationSupport()) {
3469         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3470             vshaderTxt.appendf("#extension %s : require\n", extension);
3471         }
3472         vTexCoord.addModifier("noperspective");
3473     }
3474 
3475     aVertex.appendDecl(shaderCaps, &vshaderTxt);
3476     vshaderTxt.append(";");
3477     uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
3478     vshaderTxt.append(";");
3479     uPosXform.appendDecl(shaderCaps, &vshaderTxt);
3480     vshaderTxt.append(";");
3481     vTexCoord.appendDecl(shaderCaps, &vshaderTxt);
3482     vshaderTxt.append(";");
3483 
3484     vshaderTxt.append(
3485         "// Copy Program VS\n"
3486         "void main() {"
3487         "  v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
3488         "  gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
3489         "  gl_Position.zw = vec2(0, 1);"
3490         "}"
3491     );
3492 
3493     SkString fshaderTxt(version);
3494     if (shaderCaps->noperspectiveInterpolationSupport()) {
3495         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3496             fshaderTxt.appendf("#extension %s : require\n", extension);
3497         }
3498     }
3499     if (samplerType == kTextureExternalSampler_GrSLType) {
3500         fshaderTxt.appendf("#extension %s : require\n",
3501                            shaderCaps->externalTextureExtensionString());
3502     }
3503     GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision, *shaderCaps,
3504                                                  &fshaderTxt);
3505     vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier);
3506     vTexCoord.appendDecl(shaderCaps, &fshaderTxt);
3507     fshaderTxt.append(";");
3508     uTexture.appendDecl(shaderCaps, &fshaderTxt);
3509     fshaderTxt.append(";");
3510     fshaderTxt.appendf(
3511         "// Copy Program FS\n"
3512         "void main() {"
3513         "  sk_FragColor = texture(u_texture, v_texCoord);"
3514         "}"
3515     );
3516 
3517     const char* str;
3518     GrGLint length;
3519 
3520     str = vshaderTxt.c_str();
3521     length = SkToInt(vshaderTxt.size());
3522     SkSL::Program::Settings settings;
3523     settings.fCaps = shaderCaps;
3524     SkSL::Program::Inputs inputs;
3525     GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
3526                                                   GR_GL_VERTEX_SHADER, &str, &length, 1,
3527                                                   &fStats, settings, &inputs);
3528     SkASSERT(inputs.isEmpty());
3529 
3530     str = fshaderTxt.c_str();
3531     length = SkToInt(fshaderTxt.size());
3532     GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
3533                                                   GR_GL_FRAGMENT_SHADER, &str, &length, 1,
3534                                                   &fStats, settings, &inputs);
3535     SkASSERT(inputs.isEmpty());
3536 
3537     GL_CALL(LinkProgram(fCopyPrograms[progIdx].fProgram));
3538 
3539     GL_CALL_RET(fCopyPrograms[progIdx].fTextureUniform,
3540                 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texture"));
3541     GL_CALL_RET(fCopyPrograms[progIdx].fPosXformUniform,
3542                 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_posXform"));
3543     GL_CALL_RET(fCopyPrograms[progIdx].fTexCoordXformUniform,
3544                 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordXform"));
3545 
3546     GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex"));
3547 
3548     GL_CALL(DeleteShader(vshader));
3549     GL_CALL(DeleteShader(fshader));
3550 
3551     return true;
3552 }
3553 
createMipmapProgram(int progIdx)3554 bool GrGLGpu::createMipmapProgram(int progIdx) {
3555     const bool oddWidth = SkToBool(progIdx & 0x2);
3556     const bool oddHeight = SkToBool(progIdx & 0x1);
3557     const int numTaps = (oddWidth ? 2 : 1) * (oddHeight ? 2 : 1);
3558 
3559     const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
3560 
3561     SkASSERT(!fMipmapPrograms[progIdx].fProgram);
3562     GL_CALL_RET(fMipmapPrograms[progIdx].fProgram, CreateProgram());
3563     if (!fMipmapPrograms[progIdx].fProgram) {
3564         return false;
3565     }
3566 
3567     const char* version = shaderCaps->versionDeclString();
3568     GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
3569     GrShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
3570                                GrShaderVar::kUniform_TypeModifier);
3571     GrShaderVar uTexture("u_texture", kTexture2DSampler_GrSLType,
3572                          GrShaderVar::kUniform_TypeModifier);
3573     // We need 1, 2, or 4 texture coordinates (depending on parity of each dimension):
3574     GrShaderVar vTexCoords[] = {
3575         GrShaderVar("v_texCoord0", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
3576         GrShaderVar("v_texCoord1", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
3577         GrShaderVar("v_texCoord2", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
3578         GrShaderVar("v_texCoord3", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier),
3579     };
3580     GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType,GrShaderVar::kOut_TypeModifier);
3581 
3582     SkString vshaderTxt(version);
3583     if (shaderCaps->noperspectiveInterpolationSupport()) {
3584         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3585             vshaderTxt.appendf("#extension %s : require\n", extension);
3586         }
3587         vTexCoords[0].addModifier("noperspective");
3588         vTexCoords[1].addModifier("noperspective");
3589         vTexCoords[2].addModifier("noperspective");
3590         vTexCoords[3].addModifier("noperspective");
3591     }
3592 
3593     aVertex.appendDecl(shaderCaps, &vshaderTxt);
3594     vshaderTxt.append(";");
3595     uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
3596     vshaderTxt.append(";");
3597     for (int i = 0; i < numTaps; ++i) {
3598         vTexCoords[i].appendDecl(shaderCaps, &vshaderTxt);
3599         vshaderTxt.append(";");
3600     }
3601 
3602     vshaderTxt.append(
3603         "// Mipmap Program VS\n"
3604         "void main() {"
3605         "  gl_Position.xy = a_vertex * vec2(2, 2) - vec2(1, 1);"
3606         "  gl_Position.zw = vec2(0, 1);"
3607     );
3608 
3609     // Insert texture coordinate computation:
3610     if (oddWidth && oddHeight) {
3611         vshaderTxt.append(
3612             "  v_texCoord0 = a_vertex.xy * u_texCoordXform.yw;"
3613             "  v_texCoord1 = a_vertex.xy * u_texCoordXform.yw + vec2(u_texCoordXform.x, 0);"
3614             "  v_texCoord2 = a_vertex.xy * u_texCoordXform.yw + vec2(0, u_texCoordXform.z);"
3615             "  v_texCoord3 = a_vertex.xy * u_texCoordXform.yw + u_texCoordXform.xz;"
3616         );
3617     } else if (oddWidth) {
3618         vshaderTxt.append(
3619             "  v_texCoord0 = a_vertex.xy * vec2(u_texCoordXform.y, 1);"
3620             "  v_texCoord1 = a_vertex.xy * vec2(u_texCoordXform.y, 1) + vec2(u_texCoordXform.x, 0);"
3621         );
3622     } else if (oddHeight) {
3623         vshaderTxt.append(
3624             "  v_texCoord0 = a_vertex.xy * vec2(1, u_texCoordXform.w);"
3625             "  v_texCoord1 = a_vertex.xy * vec2(1, u_texCoordXform.w) + vec2(0, u_texCoordXform.z);"
3626         );
3627     } else {
3628         vshaderTxt.append(
3629             "  v_texCoord0 = a_vertex.xy;"
3630         );
3631     }
3632 
3633     vshaderTxt.append("}");
3634 
3635     SkString fshaderTxt(version);
3636     if (shaderCaps->noperspectiveInterpolationSupport()) {
3637         if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
3638             fshaderTxt.appendf("#extension %s : require\n", extension);
3639         }
3640     }
3641     GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision, *shaderCaps,
3642                                                  &fshaderTxt);
3643     for (int i = 0; i < numTaps; ++i) {
3644         vTexCoords[i].setTypeModifier(GrShaderVar::kIn_TypeModifier);
3645         vTexCoords[i].appendDecl(shaderCaps, &fshaderTxt);
3646         fshaderTxt.append(";");
3647     }
3648     uTexture.appendDecl(shaderCaps, &fshaderTxt);
3649     fshaderTxt.append(";");
3650     fshaderTxt.append(
3651         "// Mipmap Program FS\n"
3652         "void main() {"
3653     );
3654 
3655     if (oddWidth && oddHeight) {
3656         fshaderTxt.append(
3657             "  sk_FragColor = (texture(u_texture, v_texCoord0) + "
3658             "                  texture(u_texture, v_texCoord1) + "
3659             "                  texture(u_texture, v_texCoord2) + "
3660             "                  texture(u_texture, v_texCoord3)) * 0.25;"
3661         );
3662     } else if (oddWidth || oddHeight) {
3663         fshaderTxt.append(
3664             "  sk_FragColor = (texture(u_texture, v_texCoord0) + "
3665             "                  texture(u_texture, v_texCoord1)) * 0.5;"
3666         );
3667     } else {
3668         fshaderTxt.append(
3669             "  sk_FragColor = texture(u_texture, v_texCoord0);"
3670         );
3671     }
3672 
3673     fshaderTxt.append("}");
3674 
3675     const char* str;
3676     GrGLint length;
3677 
3678     str = vshaderTxt.c_str();
3679     length = SkToInt(vshaderTxt.size());
3680     SkSL::Program::Settings settings;
3681     settings.fCaps = shaderCaps;
3682     SkSL::Program::Inputs inputs;
3683     GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
3684                                                   GR_GL_VERTEX_SHADER, &str, &length, 1,
3685                                                   &fStats, settings, &inputs);
3686     SkASSERT(inputs.isEmpty());
3687 
3688     str = fshaderTxt.c_str();
3689     length = SkToInt(fshaderTxt.size());
3690     GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
3691                                                   GR_GL_FRAGMENT_SHADER, &str, &length, 1,
3692                                                   &fStats, settings, &inputs);
3693     SkASSERT(inputs.isEmpty());
3694 
3695     GL_CALL(LinkProgram(fMipmapPrograms[progIdx].fProgram));
3696 
3697     GL_CALL_RET(fMipmapPrograms[progIdx].fTextureUniform,
3698                 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texture"));
3699     GL_CALL_RET(fMipmapPrograms[progIdx].fTexCoordXformUniform,
3700                 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texCoordXform"));
3701 
3702     GL_CALL(BindAttribLocation(fMipmapPrograms[progIdx].fProgram, 0, "a_vertex"));
3703 
3704     GL_CALL(DeleteShader(vshader));
3705     GL_CALL(DeleteShader(fshader));
3706 
3707     return true;
3708 }
3709 
createStencilClipClearProgram()3710 bool GrGLGpu::createStencilClipClearProgram() {
3711     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia"), "GrGLGpu::createStencilClipClearProgram()");
3712 
3713     if (!fStencilClipClearArrayBuffer) {
3714         static const GrGLfloat vdata[] = {-1, -1, 1, -1, -1, 1, 1, 1};
3715         fStencilClipClearArrayBuffer.reset(GrGLBuffer::Create(
3716                 this, sizeof(vdata), kVertex_GrBufferType, kStatic_GrAccessPattern, vdata));
3717         if (!fStencilClipClearArrayBuffer) {
3718             return false;
3719         }
3720     }
3721 
3722     SkASSERT(!fStencilClipClearProgram);
3723     GL_CALL_RET(fStencilClipClearProgram, CreateProgram());
3724     if (!fStencilClipClearProgram) {
3725         return false;
3726     }
3727 
3728     GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
3729     const char* version = this->caps()->shaderCaps()->versionDeclString();
3730 
3731     SkString vshaderTxt(version);
3732     aVertex.appendDecl(this->caps()->shaderCaps(), &vshaderTxt);
3733     vshaderTxt.append(";");
3734     vshaderTxt.append(
3735             "// Stencil Clip Clear Program VS\n"
3736             "void main() {"
3737             "  gl_Position = vec4(a_vertex.x, a_vertex.y, 0, 1);"
3738             "}");
3739 
3740     SkString fshaderTxt(version);
3741     GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision,
3742                                                  *this->caps()->shaderCaps(),
3743                                                  &fshaderTxt);
3744     fshaderTxt.appendf(
3745             "// Stencil Clip Clear Program FS\n"
3746             "void main() {"
3747             "  sk_FragColor = vec4(0);"
3748             "}");
3749 
3750     const char* str;
3751     GrGLint length;
3752 
3753     str = vshaderTxt.c_str();
3754     length = SkToInt(vshaderTxt.size());
3755     SkSL::Program::Settings settings;
3756     settings.fCaps = this->caps()->shaderCaps();
3757     SkSL::Program::Inputs inputs;
3758     GrGLuint vshader =
3759             GrGLCompileAndAttachShader(*fGLContext, fStencilClipClearProgram, GR_GL_VERTEX_SHADER,
3760                                        &str, &length, 1, &fStats, settings, &inputs);
3761     SkASSERT(inputs.isEmpty());
3762 
3763     str = fshaderTxt.c_str();
3764     length = SkToInt(fshaderTxt.size());
3765     GrGLuint fshader =
3766             GrGLCompileAndAttachShader(*fGLContext, fStencilClipClearProgram, GR_GL_FRAGMENT_SHADER,
3767                                        &str, &length, 1, &fStats, settings, &inputs);
3768     SkASSERT(inputs.isEmpty());
3769 
3770     GL_CALL(LinkProgram(fStencilClipClearProgram));
3771 
3772     GL_CALL(BindAttribLocation(fStencilClipClearProgram, 0, "a_vertex"));
3773 
3774     GL_CALL(DeleteShader(vshader));
3775     GL_CALL(DeleteShader(fshader));
3776 
3777     return true;
3778 }
3779 
clearStencilClipAsDraw(const GrFixedClip & clip,bool insideStencilMask,GrRenderTarget * rt)3780 void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencilMask,
3781                                      GrRenderTarget* rt) {
3782     // TODO: This should swizzle the output to match dst's config, though it is a debugging
3783     // visualization.
3784 
3785     this->handleDirtyContext();
3786     if (!fStencilClipClearProgram) {
3787         if (!this->createStencilClipClearProgram()) {
3788             SkDebugf("Failed to create stencil clip clear program.\n");
3789             return;
3790         }
3791     }
3792 
3793     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget());
3794     this->flushRenderTarget(glRT, nullptr);
3795 
3796     GL_CALL(UseProgram(fStencilClipClearProgram));
3797     fHWProgramID = fStencilClipClearProgram;
3798 
3799     fHWVertexArrayState.setVertexArrayID(this, 0);
3800 
3801     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
3802     attribs->enableVertexArrays(this, 1);
3803     attribs->set(this, 0, fStencilClipClearArrayBuffer.get(), kVec2f_GrVertexAttribType,
3804                  2 * sizeof(GrGLfloat), 0);
3805 
3806     GrXferProcessor::BlendInfo blendInfo;
3807     blendInfo.reset();
3808     this->flushBlend(blendInfo, GrSwizzle::RGBA());
3809     this->flushColorWrite(false);
3810     this->flushHWAAState(glRT, false, false);
3811     this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
3812     this->flushWindowRectangles(clip.windowRectsState(), glRT);
3813     GrStencilAttachment* sb = rt->renderTargetPriv().getStencilAttachment();
3814     // This should only be called internally when we know we have a stencil buffer.
3815     SkASSERT(sb);
3816     GrStencilSettings settings = GrStencilSettings(
3817             *GrStencilSettings::SetClipBitSettings(insideStencilMask), false, sb->bits());
3818     this->flushStencil(settings);
3819     GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
3820 }
3821 
3822 
copySurfaceAsDraw(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3823 bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
3824                                 GrSurface* src,
3825                                 const SkIRect& srcRect,
3826                                 const SkIPoint& dstPoint) {
3827     GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
3828     int progIdx = TextureToCopyProgramIdx(srcTex);
3829 
3830     if (!fCopyPrograms[progIdx].fProgram) {
3831         if (!this->createCopyProgram(srcTex)) {
3832             SkDebugf("Failed to create copy program.\n");
3833             return false;
3834         }
3835     }
3836 
3837     int w = srcRect.width();
3838     int h = srcRect.height();
3839 
3840     GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
3841     this->bindTexture(0, params, true, srcTex);
3842 
3843     GrGLIRect dstVP;
3844     this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
3845     this->flushViewport(dstVP);
3846     fHWBoundRenderTargetUniqueID.makeInvalid();
3847 
3848     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
3849 
3850     GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram));
3851     fHWProgramID = fCopyPrograms[progIdx].fProgram;
3852 
3853     fHWVertexArrayState.setVertexArrayID(this, 0);
3854 
3855     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
3856     attribs->enableVertexArrays(this, 1);
3857     attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kVec2f_GrVertexAttribType,
3858                  2 * sizeof(GrGLfloat), 0);
3859 
3860     // dst rect edges in NDC (-1 to 1)
3861     int dw = dst->width();
3862     int dh = dst->height();
3863     GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f;
3864     GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
3865     GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f;
3866     GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
3867     if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
3868         dy0 = -dy0;
3869         dy1 = -dy1;
3870     }
3871 
3872     GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft;
3873     GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w);
3874     GrGLfloat sy0 = (GrGLfloat)srcRect.fTop;
3875     GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h);
3876     int sw = src->width();
3877     int sh = src->height();
3878     if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
3879         sy0 = sh - sy0;
3880         sy1 = sh - sy1;
3881     }
3882     // src rect edges in normalized texture space (0 to 1)
3883     sx0 /= sw;
3884     sx1 /= sw;
3885     sy0 /= sh;
3886     sy1 /= sh;
3887 
3888     GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
3889     GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,
3890                       sx1 - sx0, sy1 - sy0, sx0, sy0));
3891     GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0));
3892 
3893     GrXferProcessor::BlendInfo blendInfo;
3894     blendInfo.reset();
3895     this->flushBlend(blendInfo, GrSwizzle::RGBA());
3896     this->flushColorWrite(true);
3897     this->flushHWAAState(nullptr, false, false);
3898     this->disableScissor();
3899     this->disableWindowRectangles();
3900     this->disableStencil();
3901     if (this->glCaps().srgbWriteControl()) {
3902         this->flushFramebufferSRGB(true);
3903     }
3904 
3905     GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
3906     this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst);
3907     this->didWriteToSurface(dst, &dstRect);
3908 
3909     return true;
3910 }
3911 
copySurfaceAsCopyTexSubImage(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3912 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst,
3913                                            GrSurface* src,
3914                                            const SkIRect& srcRect,
3915                                            const SkIPoint& dstPoint) {
3916     SkASSERT(can_copy_texsubimage(dst, src, this));
3917     GrGLIRect srcVP;
3918     this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
3919     GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture());
3920     SkASSERT(dstTex);
3921     // We modified the bound FBO
3922     fHWBoundRenderTargetUniqueID.makeInvalid();
3923     GrGLIRect srcGLRect;
3924     srcGLRect.setRelativeTo(srcVP,
3925                             srcRect.fLeft,
3926                             srcRect.fTop,
3927                             srcRect.width(),
3928                             srcRect.height(),
3929                             src->origin());
3930 
3931     this->setScratchTextureUnit();
3932     GL_CALL(BindTexture(dstTex->target(), dstTex->textureID()));
3933     GrGLint dstY;
3934     if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
3935         dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
3936     } else {
3937         dstY = dstPoint.fY;
3938     }
3939     GL_CALL(CopyTexSubImage2D(dstTex->target(), 0,
3940                               dstPoint.fX, dstY,
3941                               srcGLRect.fLeft, srcGLRect.fBottom,
3942                               srcGLRect.fWidth, srcGLRect.fHeight));
3943     this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, src);
3944     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
3945                                         srcRect.width(), srcRect.height());
3946     this->didWriteToSurface(dst, &dstRect);
3947 }
3948 
copySurfaceAsBlitFramebuffer(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)3949 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst,
3950                                            GrSurface* src,
3951                                            const SkIRect& srcRect,
3952                                            const SkIPoint& dstPoint) {
3953     SkASSERT(can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this));
3954     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
3955                                         srcRect.width(), srcRect.height());
3956     if (dst == src) {
3957         if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) {
3958             return false;
3959         }
3960     }
3961 
3962     GrGLIRect dstVP;
3963     GrGLIRect srcVP;
3964     this->bindSurfaceFBOForPixelOps(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
3965     this->bindSurfaceFBOForPixelOps(src, GR_GL_READ_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
3966     // We modified the bound FBO
3967     fHWBoundRenderTargetUniqueID.makeInvalid();
3968     GrGLIRect srcGLRect;
3969     GrGLIRect dstGLRect;
3970     srcGLRect.setRelativeTo(srcVP,
3971                             srcRect.fLeft,
3972                             srcRect.fTop,
3973                             srcRect.width(),
3974                             srcRect.height(),
3975                             src->origin());
3976     dstGLRect.setRelativeTo(dstVP,
3977                             dstRect.fLeft,
3978                             dstRect.fTop,
3979                             dstRect.width(),
3980                             dstRect.height(),
3981                             dst->origin());
3982 
3983     // BlitFrameBuffer respects the scissor, so disable it.
3984     this->disableScissor();
3985     this->disableWindowRectangles();
3986 
3987     GrGLint srcY0;
3988     GrGLint srcY1;
3989     // Does the blit need to y-mirror or not?
3990     if (src->origin() == dst->origin()) {
3991         srcY0 = srcGLRect.fBottom;
3992         srcY1 = srcGLRect.fBottom + srcGLRect.fHeight;
3993     } else {
3994         srcY0 = srcGLRect.fBottom + srcGLRect.fHeight;
3995         srcY1 = srcGLRect.fBottom;
3996     }
3997     GL_CALL(BlitFramebuffer(srcGLRect.fLeft,
3998                             srcY0,
3999                             srcGLRect.fLeft + srcGLRect.fWidth,
4000                             srcY1,
4001                             dstGLRect.fLeft,
4002                             dstGLRect.fBottom,
4003                             dstGLRect.fLeft + dstGLRect.fWidth,
4004                             dstGLRect.fBottom + dstGLRect.fHeight,
4005                             GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
4006     this->unbindTextureFBOForPixelOps(GR_GL_DRAW_FRAMEBUFFER, dst);
4007     this->unbindTextureFBOForPixelOps(GR_GL_READ_FRAMEBUFFER, src);
4008     this->didWriteToSurface(dst, &dstRect);
4009     return true;
4010 }
4011 
4012 // Manual implementation of mipmap generation, to work around driver bugs w/sRGB.
4013 // Uses draw calls to do a series of downsample operations to successive mips.
4014 // If this returns false, then the calling code falls back to using glGenerateMipmap.
generateMipmap(GrGLTexture * texture,bool gammaCorrect)4015 bool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) {
4016     SkASSERT(!GrPixelConfigIsSint(texture->config()));
4017     // Our iterative downsample requires the ability to limit which level we're sampling:
4018     if (!this->glCaps().doManualMipmapping()) {
4019         return false;
4020     }
4021 
4022     // Mipmaps are only supported on 2D textures:
4023     if (GR_GL_TEXTURE_2D != texture->target()) {
4024         return false;
4025     }
4026 
4027     // We need to be able to render to the texture for this to work:
4028     if (!this->glCaps().canConfigBeFBOColorAttachment(texture->config())) {
4029         return false;
4030     }
4031 
4032     // If we're mipping an sRGB texture, we need to ensure FB sRGB is correct:
4033     if (GrPixelConfigIsSRGB(texture->config())) {
4034         // If we have write-control, just set the state that we want:
4035         if (this->glCaps().srgbWriteControl()) {
4036             this->flushFramebufferSRGB(gammaCorrect);
4037         } else if (!gammaCorrect) {
4038             // If we don't have write-control we can't do non-gamma-correct mipmapping:
4039             return false;
4040         }
4041     }
4042 
4043     int width = texture->width();
4044     int height = texture->height();
4045     int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1;
4046 
4047     // Define all mips, if we haven't previously done so:
4048     if (0 == texture->texturePriv().maxMipMapLevel()) {
4049         GrGLenum internalFormat;
4050         GrGLenum externalFormat;
4051         GrGLenum externalType;
4052         if (!this->glCaps().getTexImageFormats(texture->config(), texture->config(),
4053                                                &internalFormat, &externalFormat, &externalType)) {
4054             return false;
4055         }
4056 
4057         for (GrGLint level = 1; level < levelCount; ++level) {
4058             // Define the next mip:
4059             width = SkTMax(1, width / 2);
4060             height = SkTMax(1, height / 2);
4061             GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, level, internalFormat,
4062                                                           width, height, 0,
4063                                                           externalFormat, externalType, nullptr));
4064         }
4065     }
4066 
4067     // Create (if necessary), then bind temporary FBO:
4068     if (0 == fTempDstFBOID) {
4069         GL_CALL(GenFramebuffers(1, &fTempDstFBOID));
4070     }
4071     GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID));
4072     fHWBoundRenderTargetUniqueID.makeInvalid();
4073 
4074     // Bind the texture, to get things configured for filtering.
4075     // We'll be changing our base level further below:
4076     this->setTextureUnit(0);
4077     GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kBilerp_FilterMode);
4078     this->bindTexture(0, params, gammaCorrect, texture);
4079 
4080     // Vertex data:
4081     if (!fMipmapProgramArrayBuffer) {
4082         static const GrGLfloat vdata[] = {
4083             0, 0,
4084             0, 1,
4085             1, 0,
4086             1, 1
4087         };
4088         fMipmapProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata),
4089                                                            kVertex_GrBufferType,
4090                                                            kStatic_GrAccessPattern, vdata));
4091     }
4092     if (!fMipmapProgramArrayBuffer) {
4093         return false;
4094     }
4095 
4096     fHWVertexArrayState.setVertexArrayID(this, 0);
4097 
4098     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
4099     attribs->enableVertexArrays(this, 1);
4100     attribs->set(this, 0, fMipmapProgramArrayBuffer.get(), kVec2f_GrVertexAttribType,
4101                  2 * sizeof(GrGLfloat), 0);
4102 
4103     // Set "simple" state once:
4104     GrXferProcessor::BlendInfo blendInfo;
4105     blendInfo.reset();
4106     this->flushBlend(blendInfo, GrSwizzle::RGBA());
4107     this->flushColorWrite(true);
4108     this->flushHWAAState(nullptr, false, false);
4109     this->disableScissor();
4110     this->disableWindowRectangles();
4111     this->disableStencil();
4112 
4113     // Do all the blits:
4114     width = texture->width();
4115     height = texture->height();
4116     GrGLIRect viewport;
4117     viewport.fLeft = 0;
4118     viewport.fBottom = 0;
4119     for (GrGLint level = 1; level < levelCount; ++level) {
4120         // Get and bind the program for this particular downsample (filter shape can vary):
4121         int progIdx = TextureSizeToMipmapProgramIdx(width, height);
4122         if (!fMipmapPrograms[progIdx].fProgram) {
4123             if (!this->createMipmapProgram(progIdx)) {
4124                 SkDebugf("Failed to create mipmap program.\n");
4125                 return false;
4126             }
4127         }
4128         GL_CALL(UseProgram(fMipmapPrograms[progIdx].fProgram));
4129         fHWProgramID = fMipmapPrograms[progIdx].fProgram;
4130 
4131         // Texcoord uniform is expected to contain (1/w, (w-1)/w, 1/h, (h-1)/h)
4132         const float invWidth = 1.0f / width;
4133         const float invHeight = 1.0f / height;
4134         GL_CALL(Uniform4f(fMipmapPrograms[progIdx].fTexCoordXformUniform,
4135                           invWidth, (width - 1) * invWidth, invHeight, (height - 1) * invHeight));
4136         GL_CALL(Uniform1i(fMipmapPrograms[progIdx].fTextureUniform, 0));
4137 
4138         // Only sample from previous mip
4139         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level - 1));
4140 
4141         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
4142                                      GR_GL_TEXTURE_2D, texture->textureID(), level));
4143 
4144         width = SkTMax(1, width / 2);
4145         height = SkTMax(1, height / 2);
4146         viewport.fWidth = width;
4147         viewport.fHeight = height;
4148         this->flushViewport(viewport);
4149 
4150         GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
4151     }
4152 
4153     // Unbind:
4154     GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
4155                                  GR_GL_TEXTURE_2D, 0, 0));
4156 
4157     return true;
4158 }
4159 
onQueryMultisampleSpecs(GrRenderTarget * rt,const GrStencilSettings & stencil,int * effectiveSampleCnt,SamplePattern * samplePattern)4160 void GrGLGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings& stencil,
4161                                       int* effectiveSampleCnt, SamplePattern* samplePattern) {
4162     SkASSERT(GrFSAAType::kMixedSamples != rt->fsaaType() ||
4163              rt->renderTargetPriv().getStencilAttachment() || stencil.isDisabled());
4164 
4165     this->flushStencil(stencil);
4166     this->flushHWAAState(rt, true, !stencil.isDisabled());
4167     this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyIRect());
4168 
4169     if (0 != this->caps()->maxRasterSamples()) {
4170         GR_GL_GetIntegerv(this->glInterface(), GR_GL_EFFECTIVE_RASTER_SAMPLES, effectiveSampleCnt);
4171     } else {
4172         GR_GL_GetIntegerv(this->glInterface(), GR_GL_SAMPLES, effectiveSampleCnt);
4173     }
4174 
4175     SkASSERT(*effectiveSampleCnt >= rt->numStencilSamples());
4176 
4177     if (this->caps()->sampleLocationsSupport()) {
4178         samplePattern->reset(*effectiveSampleCnt);
4179         for (int i = 0; i < *effectiveSampleCnt; ++i) {
4180             GrGLfloat pos[2];
4181             GL_CALL(GetMultisamplefv(GR_GL_SAMPLE_POSITION, i, pos));
4182             if (kTopLeft_GrSurfaceOrigin == rt->origin()) {
4183                 (*samplePattern)[i].set(pos[0], pos[1]);
4184             } else {
4185                 (*samplePattern)[i].set(pos[0], 1 - pos[1]);
4186             }
4187         }
4188     }
4189 }
4190 
xferBarrier(GrRenderTarget * rt,GrXferBarrierType type)4191 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) {
4192     SkASSERT(type);
4193     switch (type) {
4194         case kTexture_GrXferBarrierType: {
4195             GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt);
4196             if (glrt->textureFBOID() != glrt->renderFBOID()) {
4197                 // The render target uses separate storage so no need for glTextureBarrier.
4198                 // FIXME: The render target will resolve automatically when its texture is bound,
4199                 // but we could resolve only the bounds that will be read if we do it here instead.
4200                 return;
4201             }
4202             SkASSERT(this->caps()->textureBarrierSupport());
4203             GL_CALL(TextureBarrier());
4204             return;
4205         }
4206         case kBlend_GrXferBarrierType:
4207             SkASSERT(GrCaps::kAdvanced_BlendEquationSupport ==
4208                      this->caps()->blendEquationSupport());
4209             GL_CALL(BlendBarrier());
4210             return;
4211         default: break; // placate compiler warnings that kNone not handled
4212     }
4213 }
4214 
createTestingOnlyBackendTexture(void * pixels,int w,int h,GrPixelConfig config,bool)4215 GrBackendObject GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h,
4216                                                          GrPixelConfig config, bool /*isRT*/) {
4217     if (!this->caps()->isConfigTexturable(config)) {
4218         return false;
4219     }
4220     std::unique_ptr<GrGLTextureInfo> info = skstd::make_unique<GrGLTextureInfo>();
4221     info->fTarget = GR_GL_TEXTURE_2D;
4222     info->fID = 0;
4223     GL_CALL(GenTextures(1, &info->fID));
4224     GL_CALL(ActiveTexture(GR_GL_TEXTURE0));
4225     GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1));
4226     GL_CALL(BindTexture(info->fTarget, info->fID));
4227     fHWBoundTextureUniqueIDs[0].makeInvalid();
4228     GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
4229     GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
4230     GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
4231     GL_CALL(TexParameteri(info->fTarget, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
4232 
4233     GrGLenum internalFormat;
4234     GrGLenum externalFormat;
4235     GrGLenum externalType;
4236 
4237     if (!this->glCaps().getTexImageFormats(config, config, &internalFormat, &externalFormat,
4238                                            &externalType)) {
4239         return reinterpret_cast<GrBackendObject>(nullptr);
4240     }
4241 
4242     GL_CALL(TexImage2D(info->fTarget, 0, internalFormat, w, h, 0, externalFormat,
4243                        externalType, pixels));
4244 
4245     return reinterpret_cast<GrBackendObject>(info.release());
4246 }
4247 
isTestingOnlyBackendTexture(GrBackendObject id) const4248 bool GrGLGpu::isTestingOnlyBackendTexture(GrBackendObject id) const {
4249     GrGLuint texID = reinterpret_cast<const GrGLTextureInfo*>(id)->fID;
4250 
4251     GrGLboolean result;
4252     GL_CALL_RET(result, IsTexture(texID));
4253 
4254     return (GR_GL_TRUE == result);
4255 }
4256 
deleteTestingOnlyBackendTexture(GrBackendObject id,bool abandonTexture)4257 void GrGLGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandonTexture) {
4258     std::unique_ptr<const GrGLTextureInfo> info(reinterpret_cast<const GrGLTextureInfo*>(id));
4259     GrGLuint texID = info->fID;
4260 
4261     if (!abandonTexture) {
4262         GL_CALL(DeleteTextures(1, &texID));
4263     }
4264 }
4265 
resetShaderCacheForTesting() const4266 void GrGLGpu::resetShaderCacheForTesting() const {
4267     fProgramCache->abandon();
4268 }
4269 
4270 ///////////////////////////////////////////////////////////////////////////////
4271 
bindInternalVertexArray(GrGLGpu * gpu,const GrBuffer * ibuf)4272 GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu,
4273                                                                            const GrBuffer* ibuf) {
4274     GrGLAttribArrayState* attribState;
4275 
4276     if (gpu->glCaps().isCoreProfile()) {
4277         if (!fCoreProfileVertexArray) {
4278             GrGLuint arrayID;
4279             GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID));
4280             int attrCount = gpu->glCaps().maxVertexAttributes();
4281             fCoreProfileVertexArray = new GrGLVertexArray(arrayID, attrCount);
4282         }
4283         if (ibuf) {
4284             attribState = fCoreProfileVertexArray->bindWithIndexBuffer(gpu, ibuf);
4285         } else {
4286             attribState = fCoreProfileVertexArray->bind(gpu);
4287         }
4288     } else {
4289         if (ibuf) {
4290             // bindBuffer implicitly binds VAO 0 when binding an index buffer.
4291             gpu->bindBuffer(kIndex_GrBufferType, ibuf);
4292         } else {
4293             this->setVertexArrayID(gpu, 0);
4294         }
4295         int attrCount = gpu->glCaps().maxVertexAttributes();
4296         if (fDefaultVertexArrayAttribState.count() != attrCount) {
4297             fDefaultVertexArrayAttribState.resize(attrCount);
4298         }
4299         attribState = &fDefaultVertexArrayAttribState;
4300     }
4301     return attribState;
4302 }
4303 
onIsACopyNeededForTextureParams(GrTextureProxy * proxy,const GrSamplerParams & textureParams,GrTextureProducer::CopyParams * copyParams,SkScalar scaleAdjust[2]) const4304 bool GrGLGpu::onIsACopyNeededForTextureParams(GrTextureProxy* proxy,
4305                                               const GrSamplerParams& textureParams,
4306                                               GrTextureProducer::CopyParams* copyParams,
4307                                               SkScalar scaleAdjust[2]) const {
4308     const GrTexture* texture = proxy->priv().peekTexture();
4309     if (!texture) {
4310         // The only way to get and EXTERNAL or RECTANGLE texture in Ganesh is to wrap them.
4311         // In that case the proxy should already be instantiated.
4312         return false;
4313     }
4314 
4315     if (textureParams.isTiled() ||
4316         GrSamplerParams::kMipMap_FilterMode == textureParams.filterMode()) {
4317         const GrGLTexture* glTexture = static_cast<const GrGLTexture*>(texture);
4318         if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() ||
4319             GR_GL_TEXTURE_RECTANGLE == glTexture->target()) {
4320             copyParams->fFilter = GrSamplerParams::kNone_FilterMode;
4321             copyParams->fWidth = texture->width();
4322             copyParams->fHeight = texture->height();
4323             return true;
4324         }
4325     }
4326     return false;
4327 }
4328 
insertFence()4329 GrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() {
4330     SkASSERT(this->caps()->fenceSyncSupport());
4331     GrGLsync sync;
4332     GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
4333     GR_STATIC_ASSERT(sizeof(GrFence) >= sizeof(GrGLsync));
4334     return (GrFence)sync;
4335 }
4336 
waitFence(GrFence fence,uint64_t timeout)4337 bool GrGLGpu::waitFence(GrFence fence, uint64_t timeout) {
4338     GrGLenum result;
4339     GL_CALL_RET(result, ClientWaitSync((GrGLsync)fence, GR_GL_SYNC_FLUSH_COMMANDS_BIT, timeout));
4340     return (GR_GL_CONDITION_SATISFIED == result);
4341 }
4342 
deleteFence(GrFence fence) const4343 void GrGLGpu::deleteFence(GrFence fence) const {
4344     this->deleteSync((GrGLsync)fence);
4345 }
4346 
makeSemaphore(bool isOwned)4347 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrGLGpu::makeSemaphore(bool isOwned) {
4348     SkASSERT(this->caps()->fenceSyncSupport());
4349     return GrGLSemaphore::Make(this, isOwned);
4350 }
4351 
wrapBackendSemaphore(const GrBackendSemaphore & semaphore,GrWrapOwnership ownership)4352 sk_sp<GrSemaphore> GrGLGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
4353                                                  GrWrapOwnership ownership) {
4354     SkASSERT(this->caps()->fenceSyncSupport());
4355     return GrGLSemaphore::MakeWrapped(this, semaphore.glSync(), ownership);
4356 }
4357 
4358 
insertSemaphore(sk_sp<GrSemaphore> semaphore,bool flush)4359 void GrGLGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
4360     GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get());
4361 
4362     GrGLsync sync;
4363     GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
4364     glSem->setSync(sync);
4365 
4366     if (flush) {
4367         GL_CALL(Flush());
4368     }
4369 }
4370 
waitSemaphore(sk_sp<GrSemaphore> semaphore)4371 void GrGLGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
4372     GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get());
4373 
4374     GL_CALL(WaitSync(glSem->sync(), 0, GR_GL_TIMEOUT_IGNORED));
4375 }
4376 
deleteSync(GrGLsync sync) const4377 void GrGLGpu::deleteSync(GrGLsync sync) const {
4378     GL_CALL(DeleteSync(sync));
4379 }
4380 
prepareTextureForCrossContextUsage(GrTexture * texture)4381 sk_sp<GrSemaphore> GrGLGpu::prepareTextureForCrossContextUsage(GrTexture* texture) {
4382     // Set up a semaphore to be signaled once the data is ready, and flush GL
4383     sk_sp<GrSemaphore> semaphore = this->makeSemaphore(true);
4384     this->insertSemaphore(semaphore, true);
4385 
4386     return semaphore;
4387 }
4388 
TextureToCopyProgramIdx(GrTexture * texture)4389 int GrGLGpu::TextureToCopyProgramIdx(GrTexture* texture) {
4390     switch (texture->texturePriv().samplerType()) {
4391         case kTexture2DSampler_GrSLType:
4392             return 0;
4393         case kITexture2DSampler_GrSLType:
4394             return 1;
4395         case kTexture2DRectSampler_GrSLType:
4396             return 2;
4397         case kTextureExternalSampler_GrSLType:
4398             return 3;
4399         default:
4400             SkFAIL("Unexpected samper type");
4401             return 0;
4402     }
4403 }
4404