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