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