• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #include "GrGpuGL.h"
11 #include "GrGLStencilBuffer.h"
12 #include "GrTypes.h"
13 #include "SkTemplates.h"
14 
15 static const GrGLuint GR_MAX_GLUINT = ~0;
16 static const GrGLint  GR_INVAL_GLINT = ~0;
17 
18 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
19 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
20 
21 // we use a spare texture unit to avoid
22 // mucking with the state of any of the stages.
23 static const int SPARE_TEX_UNIT = GrDrawState::kNumStages;
24 
25 #define SKIP_CACHE_CHECK    true
26 
27 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
28     #define CLEAR_ERROR_BEFORE_ALLOC(iface)   GrGLClearErr(iface)
29     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL_NOERRCHECK(iface, call)
30     #define CHECK_ALLOC_ERROR(iface)          GR_GL_GET_ERROR(iface)
31 #else
32     #define CLEAR_ERROR_BEFORE_ALLOC(iface)
33     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL(iface, call)
34     #define CHECK_ALLOC_ERROR(iface)          GR_GL_NO_ERROR
35 #endif
36 
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 static const GrGLenum gXfermodeCoeff2Blend[] = {
41     GR_GL_ZERO,
42     GR_GL_ONE,
43     GR_GL_SRC_COLOR,
44     GR_GL_ONE_MINUS_SRC_COLOR,
45     GR_GL_DST_COLOR,
46     GR_GL_ONE_MINUS_DST_COLOR,
47     GR_GL_SRC_ALPHA,
48     GR_GL_ONE_MINUS_SRC_ALPHA,
49     GR_GL_DST_ALPHA,
50     GR_GL_ONE_MINUS_DST_ALPHA,
51     GR_GL_CONSTANT_COLOR,
52     GR_GL_ONE_MINUS_CONSTANT_COLOR,
53     GR_GL_CONSTANT_ALPHA,
54     GR_GL_ONE_MINUS_CONSTANT_ALPHA,
55 
56     // extended blend coeffs
57     GR_GL_SRC1_COLOR,
58     GR_GL_ONE_MINUS_SRC1_COLOR,
59     GR_GL_SRC1_ALPHA,
60     GR_GL_ONE_MINUS_SRC1_ALPHA,
61 };
62 
BlendCoeffReferencesConstant(GrBlendCoeff coeff)63 bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) {
64     static const bool gCoeffReferencesBlendConst[] = {
65         false,
66         false,
67         false,
68         false,
69         false,
70         false,
71         false,
72         false,
73         false,
74         false,
75         true,
76         true,
77         true,
78         true,
79 
80         // extended blend coeffs
81         false,
82         false,
83         false,
84         false,
85     };
86     return gCoeffReferencesBlendConst[coeff];
87     GR_STATIC_ASSERT(kTotalBlendCoeffCount == GR_ARRAY_COUNT(gCoeffReferencesBlendConst));
88 
89     GR_STATIC_ASSERT(0 == kZero_BlendCoeff);
90     GR_STATIC_ASSERT(1 == kOne_BlendCoeff);
91     GR_STATIC_ASSERT(2 == kSC_BlendCoeff);
92     GR_STATIC_ASSERT(3 == kISC_BlendCoeff);
93     GR_STATIC_ASSERT(4 == kDC_BlendCoeff);
94     GR_STATIC_ASSERT(5 == kIDC_BlendCoeff);
95     GR_STATIC_ASSERT(6 == kSA_BlendCoeff);
96     GR_STATIC_ASSERT(7 == kISA_BlendCoeff);
97     GR_STATIC_ASSERT(8 == kDA_BlendCoeff);
98     GR_STATIC_ASSERT(9 == kIDA_BlendCoeff);
99     GR_STATIC_ASSERT(10 == kConstC_BlendCoeff);
100     GR_STATIC_ASSERT(11 == kIConstC_BlendCoeff);
101     GR_STATIC_ASSERT(12 == kConstA_BlendCoeff);
102     GR_STATIC_ASSERT(13 == kIConstA_BlendCoeff);
103 
104     GR_STATIC_ASSERT(14 == kS2C_BlendCoeff);
105     GR_STATIC_ASSERT(15 == kIS2C_BlendCoeff);
106     GR_STATIC_ASSERT(16 == kS2A_BlendCoeff);
107     GR_STATIC_ASSERT(17 == kIS2A_BlendCoeff);
108 
109     // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope
110     GR_STATIC_ASSERT(kTotalBlendCoeffCount == GR_ARRAY_COUNT(gXfermodeCoeff2Blend));
111 }
112 
113 ///////////////////////////////////////////////////////////////////////////////
114 
AdjustTextureMatrix(const GrGLTexture * texture,GrSamplerState::SampleMode mode,GrMatrix * matrix)115 void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture,
116                                   GrSamplerState::SampleMode mode,
117                                   GrMatrix* matrix) {
118     GrAssert(NULL != texture);
119     GrAssert(NULL != matrix);
120     GrGLTexture::Orientation orientation = texture->orientation();
121     if (GrGLTexture::kBottomUp_Orientation == orientation) {
122         GrMatrix invY;
123         invY.setAll(GR_Scalar1, 0,           0,
124                     0,          -GR_Scalar1, GR_Scalar1,
125                     0,          0,           GrMatrix::I()[8]);
126         matrix->postConcat(invY);
127     } else {
128         GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
129     }
130 }
131 
TextureMatrixIsIdentity(const GrGLTexture * texture,const GrSamplerState & sampler)132 bool GrGpuGL::TextureMatrixIsIdentity(const GrGLTexture* texture,
133                                       const GrSamplerState& sampler) {
134     GrAssert(NULL != texture);
135     if (!sampler.getMatrix().isIdentity()) {
136         return false;
137     }
138     GrGLTexture::Orientation orientation = texture->orientation();
139     if (GrGLTexture::kBottomUp_Orientation == orientation) {
140         return false;
141     } else {
142         GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
143     }
144     return true;
145 }
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 
149 static bool gPrintStartupSpew;
150 
fbo_test(const GrGLInterface * gl,int w,int h)151 static bool fbo_test(const GrGLInterface* gl, int w, int h) {
152 
153     GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT));
154 
155     GrGLuint testFBO;
156     GR_GL_CALL(gl, GenFramebuffers(1, &testFBO));
157     GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, testFBO));
158     GrGLuint testRTTex;
159     GR_GL_CALL(gl, GenTextures(1, &testRTTex));
160     GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, testRTTex));
161     // some implementations require texture to be mip-map complete before
162     // FBO with level 0 bound as color attachment will be framebuffer complete.
163     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
164                                  GR_GL_TEXTURE_MIN_FILTER,
165                                  GR_GL_NEAREST));
166     GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D, 0, GR_GL_RGBA, w, h,
167                               0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, NULL));
168     GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
169     GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
170                                         GR_GL_COLOR_ATTACHMENT0,
171                                         GR_GL_TEXTURE_2D, testRTTex, 0));
172     GrGLenum status;
173     GR_GL_CALL_RET(gl, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
174     GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO));
175     GR_GL_CALL(gl, DeleteTextures(1, &testRTTex));
176 
177     return status == GR_GL_FRAMEBUFFER_COMPLETE;
178 }
179 
GrGpuGL(const GrGLContextInfo & ctxInfo)180 GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo) : fGLContextInfo(ctxInfo) {
181 
182     GrAssert(ctxInfo.isInitialized());
183 
184     fPrintedCaps = false;
185 
186     GrGLClearErr(fGLContextInfo.interface());
187 
188     if (gPrintStartupSpew) {
189         const GrGLubyte* ext;
190         GL_CALL_RET(ext, GetString(GR_GL_EXTENSIONS));
191         const GrGLubyte* vendor;
192         const GrGLubyte* renderer;
193         const GrGLubyte* version;
194         GL_CALL_RET(vendor, GetString(GR_GL_VENDOR));
195         GL_CALL_RET(renderer, GetString(GR_GL_RENDERER));
196         GL_CALL_RET(version, GetString(GR_GL_VERSION));
197         GrPrintf("------------------------- create GrGpuGL %p --------------\n",
198                  this);
199         GrPrintf("------ VENDOR %s\n", vendor);
200         GrPrintf("------ RENDERER %s\n", renderer);
201         GrPrintf("------ VERSION %s\n",  version);
202         GrPrintf("------ EXTENSIONS\n %s \n", ext);
203     }
204 
205     this->resetDirtyFlags();
206 
207     this->initCaps();
208 
209     fLastSuccessfulStencilFmtIdx = 0;
210     fCanPreserveUnpremulRoundtrip = kUnknown_CanPreserveUnpremulRoundtrip;
211 }
212 
~GrGpuGL()213 GrGpuGL::~GrGpuGL() {
214     // This must be called by before the GrDrawTarget destructor
215     this->releaseGeometry();
216     // This subclass must do this before the base class destructor runs
217     // since we will unref the GrGLInterface.
218     this->releaseResources();
219 }
220 
221 ///////////////////////////////////////////////////////////////////////////////
222 
initCaps()223 void GrGpuGL::initCaps() {
224     GrGLint maxTextureUnits;
225     // check FS and fixed-function texture unit limits
226     // we only use textures in the fragment stage currently.
227     // checks are > to make sure we have a spare unit.
228     const GrGLInterface* gl = this->glInterface();
229     GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
230     GrAssert(maxTextureUnits > GrDrawState::kNumStages);
231     if (kES2_GrGLBinding != this->glBinding()) {
232         GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_UNITS, &maxTextureUnits);
233         GrAssert(maxTextureUnits > GrDrawState::kNumStages);
234     }
235 
236     GrGLint numFormats;
237     GR_GL_GetIntegerv(gl, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
238     SkAutoSTMalloc<10, GrGLint> formats(numFormats);
239     GR_GL_GetIntegerv(gl, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
240     for (int i = 0; i < numFormats; ++i) {
241         if (formats[i] == GR_GL_PALETTE8_RGBA8) {
242             fCaps.f8BitPaletteSupport = true;
243             break;
244         }
245     }
246 
247     if (kDesktop_GrGLBinding == this->glBinding()) {
248         // we could also look for GL_ATI_separate_stencil extension or
249         // GL_EXT_stencil_two_side but they use different function signatures
250         // than GL2.0+ (and than each other).
251         fCaps.fTwoSidedStencilSupport = (this->glVersion() >= GR_GL_VER(2,0));
252         // supported on GL 1.4 and higher or by extension
253         fCaps.fStencilWrapOpsSupport = (this->glVersion() >= GR_GL_VER(1,4)) ||
254                                        this->hasExtension("GL_EXT_stencil_wrap");
255     } else {
256         // ES 2 has two sided stencil and stencil wrap
257         fCaps.fTwoSidedStencilSupport = true;
258         fCaps.fStencilWrapOpsSupport = true;
259     }
260 
261     if (kDesktop_GrGLBinding == this->glBinding()) {
262         fCaps.fBufferLockSupport = true; // we require VBO support and the desktop VBO
263                                          // extension includes glMapBuffer.
264     } else {
265         fCaps.fBufferLockSupport = this->hasExtension("GL_OES_mapbuffer");
266     }
267 
268     if (kDesktop_GrGLBinding == this->glBinding()) {
269         if (this->glVersion() >= GR_GL_VER(2,0) ||
270             this->hasExtension("GL_ARB_texture_non_power_of_two")) {
271             fCaps.fNPOTTextureTileSupport = true;
272         } else {
273             fCaps.fNPOTTextureTileSupport = false;
274         }
275     } else {
276         // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
277         fCaps.fNPOTTextureTileSupport = this->hasExtension("GL_OES_texture_npot");
278     }
279 
280     fCaps.fHWAALineSupport = (kDesktop_GrGLBinding == this->glBinding());
281 
282     ////////////////////////////////////////////////////////////////////////////
283     // Experiments to determine limitations that can't be queried.
284     // TODO: Make these a preprocess that generate some compile time constants.
285     // TODO: probe once at startup, rather than once per context creation.
286 
287     GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_SIZE, &fCaps.fMaxTextureSize);
288     GR_GL_GetIntegerv(gl, GR_GL_MAX_RENDERBUFFER_SIZE, &fCaps.fMaxRenderTargetSize);
289     // Our render targets are always created with textures as the color
290     // attachment, hence this min:
291     fCaps.fMaxRenderTargetSize = GrMin(fCaps.fMaxTextureSize, fCaps.fMaxRenderTargetSize);
292 
293     fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType();
294 }
295 
canPreserveReadWriteUnpremulPixels()296 bool GrGpuGL::canPreserveReadWriteUnpremulPixels() {
297     if (kUnknown_CanPreserveUnpremulRoundtrip ==
298         fCanPreserveUnpremulRoundtrip) {
299 
300         SkAutoTMalloc<uint32_t> data(256 * 256 * 3);
301         uint32_t* srcData = data.get();
302         uint32_t* firstRead = data.get() + 256 * 256;
303         uint32_t* secondRead = data.get() + 2 * 256 * 256;
304 
305         for (int y = 0; y < 256; ++y) {
306             for (int x = 0; x < 256; ++x) {
307                 uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[256*y + x]);
308                 color[3] = y;
309                 color[2] = x;
310                 color[1] = x;
311                 color[0] = x;
312             }
313         }
314 
315         // We have broader support for read/write pixels on render targets
316         // than on textures.
317         GrTextureDesc dstDesc;
318         dstDesc.fFlags = kRenderTarget_GrTextureFlagBit |
319                          kNoStencil_GrTextureFlagBit;
320         dstDesc.fWidth = 256;
321         dstDesc.fHeight = 256;
322         dstDesc.fConfig = kRGBA_8888_GrPixelConfig;
323         dstDesc.fSampleCnt = 0;
324 
325         SkAutoTUnref<GrTexture> dstTex(this->createTexture(dstDesc, NULL, 0));
326         if (!dstTex.get()) {
327             return false;
328         }
329         GrRenderTarget* rt = dstTex.get()->asRenderTarget();
330         GrAssert(NULL != rt);
331 
332         bool failed = true;
333         static const UnpremulConversion gMethods[] = {
334             kUpOnWrite_DownOnRead_UnpremulConversion,
335             kDownOnWrite_UpOnRead_UnpremulConversion,
336         };
337 
338         // pretend that we can do the roundtrip to avoid recursive calls to
339         // this function
340         fCanPreserveUnpremulRoundtrip = kYes_CanPreserveUnpremulRoundtrip;
341         for (size_t i = 0; i < GR_ARRAY_COUNT(gMethods) && failed; ++i) {
342             fUnpremulConversion = gMethods[i];
343             rt->writePixels(0, 0,
344                             256, 256,
345                             kRGBA_8888_UPM_GrPixelConfig, srcData, 0);
346             rt->readPixels(0, 0,
347                            256, 256,
348                            kRGBA_8888_UPM_GrPixelConfig, firstRead, 0);
349             rt->writePixels(0, 0,
350                             256, 256,
351                             kRGBA_8888_UPM_GrPixelConfig, firstRead, 0);
352             rt->readPixels(0, 0,
353                            256, 256,
354                            kRGBA_8888_UPM_GrPixelConfig, secondRead, 0);
355             failed = false;
356             for (int j = 0; j < 256 * 256; ++j) {
357                 if (firstRead[j] != secondRead[j]) {
358                     failed = true;
359                     break;
360                 }
361             }
362         }
363         fCanPreserveUnpremulRoundtrip = failed ?
364                         kNo_CanPreserveUnpremulRoundtrip :
365                         kYes_CanPreserveUnpremulRoundtrip;
366     }
367 
368     if (kYes_CanPreserveUnpremulRoundtrip == fCanPreserveUnpremulRoundtrip) {
369         return true;
370     } else {
371         return false;
372     }
373 }
374 
preferredReadPixelsConfig(GrPixelConfig config) const375 GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig config) const {
376     if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) {
377         return GrPixelConfigSwapRAndB(config);
378     } else {
379         return config;
380     }
381 }
382 
preferredWritePixelsConfig(GrPixelConfig config) const383 GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig config) const {
384     if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) {
385         return GrPixelConfigSwapRAndB(config);
386     } else {
387         return config;
388     }
389 }
390 
fullReadPixelsIsFasterThanPartial() const391 bool GrGpuGL::fullReadPixelsIsFasterThanPartial() const {
392     return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL);
393 }
394 
onResetContext()395 void GrGpuGL::onResetContext() {
396     if (gPrintStartupSpew && !fPrintedCaps) {
397         fPrintedCaps = true;
398         this->getCaps().print();
399         this->glCaps().print();
400     }
401 
402     // We detect cases when blending is effectively off
403     fHWBlendDisabled = false;
404     GL_CALL(Enable(GR_GL_BLEND));
405 
406     // we don't use the zb at all
407     GL_CALL(Disable(GR_GL_DEPTH_TEST));
408     GL_CALL(DepthMask(GR_GL_FALSE));
409 
410     GL_CALL(Disable(GR_GL_CULL_FACE));
411     GL_CALL(FrontFace(GR_GL_CCW));
412     fHWDrawState.setDrawFace(GrDrawState::kBoth_DrawFace);
413 
414     GL_CALL(Disable(GR_GL_DITHER));
415     if (kDesktop_GrGLBinding == this->glBinding()) {
416         GL_CALL(Disable(GR_GL_LINE_SMOOTH));
417         GL_CALL(Disable(GR_GL_POINT_SMOOTH));
418         GL_CALL(Disable(GR_GL_MULTISAMPLE));
419         fHWAAState.fMSAAEnabled = false;
420         fHWAAState.fSmoothLineEnabled = false;
421     }
422 
423     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
424     fHWDrawState.resetStateFlags();
425 
426     // we only ever use lines in hairline mode
427     GL_CALL(LineWidth(1));
428 
429     // invalid
430     fActiveTextureUnitIdx = -1;
431 
432     // illegal values
433     fHWDrawState.setBlendFunc((GrBlendCoeff)0xFF, (GrBlendCoeff)0xFF);
434 
435     fHWDrawState.setBlendConstant(0x00000000);
436     GL_CALL(BlendColor(0,0,0,0));
437 
438     fHWDrawState.setColor(GrColor_ILLEGAL);
439 
440     fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
441 
442     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
443         fHWDrawState.setTexture(s, NULL);
444         fHWDrawState.sampler(s)->setRadial2Params(-GR_ScalarMax,
445                                                   -GR_ScalarMax,
446                                                   true);
447         *fHWDrawState.sampler(s)->matrix() = GrMatrix::InvalidMatrix();
448         fHWDrawState.sampler(s)->setConvolutionParams(0, NULL);
449     }
450 
451     fHWBounds.fScissorRect.invalidate();
452     fHWBounds.fScissorEnabled = false;
453     GL_CALL(Disable(GR_GL_SCISSOR_TEST));
454     fHWBounds.fViewportRect.invalidate();
455 
456     fHWDrawState.stencil()->invalidate();
457     fHWStencilClip = false;
458     fClipInStencil = false;
459 
460     fHWGeometryState.fIndexBuffer = NULL;
461     fHWGeometryState.fVertexBuffer = NULL;
462 
463     fHWGeometryState.fArrayPtrsDirty = true;
464 
465     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
466     fHWDrawState.setRenderTarget(NULL);
467 
468     // we assume these values
469     if (this->glCaps().unpackRowLengthSupport()) {
470         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
471     }
472     if (this->glCaps().packRowLengthSupport()) {
473         GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
474     }
475     if (this->glCaps().unpackFlipYSupport()) {
476         GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
477     }
478     if (this->glCaps().packFlipYSupport()) {
479         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
480     }
481 }
482 
onCreatePlatformTexture(const GrPlatformTextureDesc & desc)483 GrTexture* GrGpuGL::onCreatePlatformTexture(const GrPlatformTextureDesc& desc) {
484     GrGLTexture::Desc glTexDesc;
485     if (!configToGLFormats(desc.fConfig, false, NULL, NULL, NULL)) {
486         return NULL;
487     }
488 
489     glTexDesc.fWidth = desc.fWidth;
490     glTexDesc.fHeight = desc.fHeight;
491     glTexDesc.fConfig = desc.fConfig;
492     glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
493     glTexDesc.fOwnsID = false;
494     glTexDesc.fOrientation = GrGLTexture::kBottomUp_Orientation;
495 
496     GrGLTexture* texture = NULL;
497     if (desc.fFlags & kRenderTarget_GrPlatformTextureFlag) {
498         GrGLRenderTarget::Desc glRTDesc;
499         glRTDesc.fRTFBOID = 0;
500         glRTDesc.fTexFBOID = 0;
501         glRTDesc.fMSColorRenderbufferID = 0;
502         glRTDesc.fOwnIDs = true;
503         glRTDesc.fConfig = desc.fConfig;
504         glRTDesc.fSampleCnt = desc.fSampleCnt;
505         if (!this->createRenderTargetObjects(glTexDesc.fWidth,
506                                              glTexDesc.fHeight,
507                                              glTexDesc.fTextureID,
508                                              &glRTDesc)) {
509             return NULL;
510         }
511         texture = new GrGLTexture(this, glTexDesc, glRTDesc);
512     } else {
513         texture = new GrGLTexture(this, glTexDesc);
514     }
515     if (NULL == texture) {
516         return NULL;
517     }
518 
519     this->setSpareTextureUnit();
520     return texture;
521 }
522 
onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc & desc)523 GrRenderTarget* GrGpuGL::onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
524     GrGLRenderTarget::Desc glDesc;
525     glDesc.fConfig = desc.fConfig;
526     glDesc.fRTFBOID = static_cast<GrGLuint>(desc.fRenderTargetHandle);
527     glDesc.fMSColorRenderbufferID = 0;
528     glDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
529     glDesc.fSampleCnt = desc.fSampleCnt;
530     glDesc.fOwnIDs = false;
531     GrGLIRect viewport;
532     viewport.fLeft   = 0;
533     viewport.fBottom = 0;
534     viewport.fWidth  = desc.fWidth;
535     viewport.fHeight = desc.fHeight;
536 
537     GrRenderTarget* tgt = new GrGLRenderTarget(this, glDesc, viewport);
538     if (desc.fStencilBits) {
539         GrGLStencilBuffer::Format format;
540         format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat;
541         format.fPacked = false;
542         format.fStencilBits = desc.fStencilBits;
543         format.fTotalBits = desc.fStencilBits;
544         GrGLStencilBuffer* sb = new GrGLStencilBuffer(this,
545                                                       0,
546                                                       desc.fWidth,
547                                                       desc.fHeight,
548                                                       desc.fSampleCnt,
549                                                       format);
550         tgt->setStencilBuffer(sb);
551         sb->unref();
552     }
553     return tgt;
554 }
555 
556 ////////////////////////////////////////////////////////////////////////////////
557 
onWriteTexturePixels(GrTexture * texture,int left,int top,int width,int height,GrPixelConfig config,const void * buffer,size_t rowBytes)558 void GrGpuGL::onWriteTexturePixels(GrTexture* texture,
559                                    int left, int top, int width, int height,
560                                    GrPixelConfig config, const void* buffer,
561                                    size_t rowBytes) {
562     if (NULL == buffer) {
563         return;
564     }
565     GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
566 
567     this->setSpareTextureUnit();
568     GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
569     GrGLTexture::Desc desc;
570     desc.fConfig = glTex->config();
571     desc.fWidth = glTex->width();
572     desc.fHeight = glTex->height();
573     desc.fOrientation = glTex->orientation();
574     desc.fTextureID = glTex->textureID();
575 
576     this->uploadTexData(desc, false,
577                         left, top, width, height,
578                         config, buffer, rowBytes);
579 }
580 
581 namespace {
adjust_pixel_ops_params(int surfaceWidth,int surfaceHeight,size_t bpp,int * left,int * top,int * width,int * height,const void ** data,size_t * rowBytes)582 bool adjust_pixel_ops_params(int surfaceWidth,
583                              int surfaceHeight,
584                              size_t bpp,
585                              int* left, int* top, int* width, int* height,
586                              const void** data,
587                              size_t* rowBytes) {
588     if (!*rowBytes) {
589         *rowBytes = *width * bpp;
590     }
591 
592     GrIRect subRect = GrIRect::MakeXYWH(*left, *top, *width, *height);
593     GrIRect bounds = GrIRect::MakeWH(surfaceWidth, surfaceHeight);
594 
595     if (!subRect.intersect(bounds)) {
596         return false;
597     }
598     *data = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>(*data) +
599           (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp);
600 
601     *left = subRect.fLeft;
602     *top = subRect.fTop;
603     *width = subRect.width();
604     *height = subRect.height();
605     return true;
606 }
607 }
608 
uploadTexData(const GrGLTexture::Desc & desc,bool isNewTexture,int left,int top,int width,int height,GrPixelConfig dataConfig,const void * data,size_t rowBytes)609 bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
610                             bool isNewTexture,
611                             int left, int top, int width, int height,
612                             GrPixelConfig dataConfig,
613                             const void* data,
614                             size_t rowBytes) {
615     GrAssert(NULL != data || isNewTexture);
616 
617     size_t bpp = GrBytesPerPixel(dataConfig);
618     if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top,
619                                  &width, &height, &data, &rowBytes)) {
620         return false;
621     }
622     size_t trimRowBytes = width * bpp;
623 
624     // in case we need a temporary, trimmed copy of the src pixels
625     SkAutoSMalloc<128 * 128> tempStorage;
626 
627     bool useTexStorage = isNewTexture &&
628                          this->glCaps().texStorageSupport();
629     if (useTexStorage) {
630         if (kDesktop_GrGLBinding == this->glBinding()) {
631             // 565 is not a sized internal format on desktop GL. So on desktop
632             // with 565 we always use an unsized internal format to let the
633             // system pick the best sized format to convert the 565 data to.
634             // Since glTexStorage only allows sized internal formats we will
635             // instead fallback to glTexImage2D.
636             useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig;
637         } else {
638             // ES doesn't allow paletted textures to be used with tex storage
639             useTexStorage = desc.fConfig != kIndex_8_GrPixelConfig;
640         }
641     }
642 
643     GrGLenum internalFormat;
644     GrGLenum externalFormat;
645     GrGLenum externalType;
646     // glTexStorage requires sized internal formats on both desktop and ES. ES
647     // glTexImage requires an unsized format.
648     if (!this->configToGLFormats(dataConfig, useTexStorage, &internalFormat,
649                                  &externalFormat, &externalType)) {
650         return false;
651     }
652 
653     if (!isNewTexture && GR_GL_PALETTE8_RGBA8 == internalFormat) {
654         // paletted textures cannot be updated
655         return false;
656     }
657 
658     /*
659      *  check whether to allocate a temporary buffer for flipping y or
660      *  because our srcData has extra bytes past each row. If so, we need
661      *  to trim those off here, since GL ES may not let us specify
662      *  GL_UNPACK_ROW_LENGTH.
663      */
664     bool restoreGLRowLength = false;
665     bool swFlipY = false;
666     bool glFlipY = false;
667     if (NULL != data) {
668         if (GrGLTexture::kBottomUp_Orientation == desc.fOrientation) {
669             if (this->glCaps().unpackFlipYSupport()) {
670                 glFlipY = true;
671             } else {
672                 swFlipY = true;
673             }
674         }
675         if (this->glCaps().unpackRowLengthSupport() && !swFlipY) {
676             // can't use this for flipping, only non-neg values allowed. :(
677             if (rowBytes != trimRowBytes) {
678                 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
679                 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
680                 restoreGLRowLength = true;
681             }
682         } else {
683             if (trimRowBytes != rowBytes || swFlipY) {
684                 // copy data into our new storage, skipping the trailing bytes
685                 size_t trimSize = height * trimRowBytes;
686                 const char* src = (const char*)data;
687                 if (swFlipY) {
688                     src += (height - 1) * rowBytes;
689                 }
690                 char* dst = (char*)tempStorage.reset(trimSize);
691                 for (int y = 0; y < height; y++) {
692                     memcpy(dst, src, trimRowBytes);
693                     if (swFlipY) {
694                         src -= rowBytes;
695                     } else {
696                         src += rowBytes;
697                     }
698                     dst += trimRowBytes;
699                 }
700                 // now point data to our copied version
701                 data = tempStorage.get();
702             }
703         }
704         if (glFlipY) {
705             GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
706         }
707         GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, static_cast<GrGLint>(bpp)));
708     }
709     bool succeeded = true;
710     if (isNewTexture &&
711         0 == left && 0 == top &&
712         desc.fWidth == width && desc.fHeight == height) {
713         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
714         if (useTexStorage) {
715             // We never resize  or change formats of textures. We don't use
716             // mipmaps currently.
717             GL_ALLOC_CALL(this->glInterface(),
718                           TexStorage2D(GR_GL_TEXTURE_2D,
719                                        1, // levels
720                                        internalFormat,
721                                        desc.fWidth, desc.fHeight));
722         } else {
723             if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
724                 GrGLsizei imageSize = desc.fWidth * desc.fHeight +
725                                       kGrColorTableSize;
726                 GL_ALLOC_CALL(this->glInterface(),
727                               CompressedTexImage2D(GR_GL_TEXTURE_2D,
728                                                    0, // level
729                                                    internalFormat,
730                                                    desc.fWidth, desc.fHeight,
731                                                    0, // border
732                                                    imageSize,
733                                                    data));
734             } else {
735                 GL_ALLOC_CALL(this->glInterface(),
736                               TexImage2D(GR_GL_TEXTURE_2D,
737                                          0, // level
738                                          internalFormat,
739                                          desc.fWidth, desc.fHeight,
740                                          0, // border
741                                          externalFormat, externalType,
742                                          data));
743             }
744         }
745         GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
746         if (error != GR_GL_NO_ERROR) {
747             succeeded = false;
748         } else {
749             // if we have data and we used TexStorage to create the texture, we
750             // now upload with TexSubImage.
751             if (NULL != data && useTexStorage) {
752                 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
753                                       0, // level
754                                       left, top,
755                                       width, height,
756                                       externalFormat, externalType,
757                                       data));
758             }
759         }
760     } else {
761         if (swFlipY || glFlipY) {
762             top = desc.fHeight - (top + height);
763         }
764         GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
765                               0, // level
766                               left, top,
767                               width, height,
768                               externalFormat, externalType, data));
769     }
770 
771     if (restoreGLRowLength) {
772         GrAssert(this->glCaps().unpackRowLengthSupport());
773         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
774     }
775     if (glFlipY) {
776         GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
777     }
778     return succeeded;
779 }
780 
createRenderTargetObjects(int width,int height,GrGLuint texID,GrGLRenderTarget::Desc * desc)781 bool GrGpuGL::createRenderTargetObjects(int width, int height,
782                                         GrGLuint texID,
783                                         GrGLRenderTarget::Desc* desc) {
784     desc->fMSColorRenderbufferID = 0;
785     desc->fRTFBOID = 0;
786     desc->fTexFBOID = 0;
787     desc->fOwnIDs = true;
788 
789     GrGLenum status;
790     GrGLint err;
791 
792     GrGLenum msColorFormat = 0; // suppress warning
793 
794     GL_CALL(GenFramebuffers(1, &desc->fTexFBOID));
795     if (!desc->fTexFBOID) {
796         goto FAILED;
797     }
798 
799 
800     // If we are using multisampling we will create two FBOS. We render
801     // to one and then resolve to the texture bound to the other.
802     if (desc->fSampleCnt > 0) {
803         if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
804             goto FAILED;
805         }
806         GL_CALL(GenFramebuffers(1, &desc->fRTFBOID));
807         GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID));
808         if (!desc->fRTFBOID ||
809             !desc->fMSColorRenderbufferID ||
810             !this->configToGLFormats(desc->fConfig,
811                                      // GLES requires sized internal formats
812                                      kES2_GrGLBinding == this->glBinding(),
813                                      &msColorFormat, NULL, NULL)) {
814             goto FAILED;
815         }
816     } else {
817         desc->fRTFBOID = desc->fTexFBOID;
818     }
819 
820     // below here we may bind the FBO
821     fHWDrawState.setRenderTarget(NULL);
822     if (desc->fRTFBOID != desc->fTexFBOID) {
823         GrAssert(desc->fSampleCnt > 1);
824         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER,
825                                desc->fMSColorRenderbufferID));
826         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
827         GL_ALLOC_CALL(this->glInterface(),
828                       RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
829                                                      desc->fSampleCnt,
830                                                      msColorFormat,
831                                                      width, height));
832         err = CHECK_ALLOC_ERROR(this->glInterface());
833         if (err != GR_GL_NO_ERROR) {
834             goto FAILED;
835         }
836         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fRTFBOID));
837         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
838                                       GR_GL_COLOR_ATTACHMENT0,
839                                       GR_GL_RENDERBUFFER,
840                                       desc->fMSColorRenderbufferID));
841         if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
842             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
843             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
844                 goto FAILED;
845             }
846             fGLContextInfo.caps().markConfigAsValidColorAttachment(
847                                                                 desc->fConfig);
848         }
849     }
850     GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
851 
852     GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
853                                  GR_GL_COLOR_ATTACHMENT0,
854                                  GR_GL_TEXTURE_2D,
855                                  texID, 0));
856     if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
857         GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
858         if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
859             goto FAILED;
860         }
861         fGLContextInfo.caps().markConfigAsValidColorAttachment(desc->fConfig);
862     }
863 
864     return true;
865 
866 FAILED:
867     if (desc->fMSColorRenderbufferID) {
868         GL_CALL(DeleteRenderbuffers(1, &desc->fMSColorRenderbufferID));
869     }
870     if (desc->fRTFBOID != desc->fTexFBOID) {
871         GL_CALL(DeleteFramebuffers(1, &desc->fRTFBOID));
872     }
873     if (desc->fTexFBOID) {
874         GL_CALL(DeleteFramebuffers(1, &desc->fTexFBOID));
875     }
876     return false;
877 }
878 
879 // good to set a break-point here to know when createTexture fails
return_null_texture()880 static GrTexture* return_null_texture() {
881 //    GrAssert(!"null texture");
882     return NULL;
883 }
884 
885 #if GR_DEBUG
as_size_t(int x)886 static size_t as_size_t(int x) {
887     return x;
888 }
889 #endif
890 
onCreateTexture(const GrTextureDesc & desc,const void * srcData,size_t rowBytes)891 GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
892                                     const void* srcData,
893                                     size_t rowBytes) {
894 
895 #if GR_COLLECT_STATS
896     ++fStats.fTextureCreateCnt;
897 #endif
898 
899     GrGLTexture::Desc glTexDesc;
900     GrGLRenderTarget::Desc  glRTDesc;
901 
902     // Attempt to catch un- or wrongly initialized sample counts;
903     GrAssert(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64);
904 
905     glTexDesc.fWidth  = desc.fWidth;
906     glTexDesc.fHeight = desc.fHeight;
907     glTexDesc.fConfig = desc.fConfig;
908     glTexDesc.fOwnsID = true;
909 
910     glRTDesc.fMSColorRenderbufferID = 0;
911     glRTDesc.fRTFBOID = 0;
912     glRTDesc.fTexFBOID = 0;
913     glRTDesc.fOwnIDs = true;
914     glRTDesc.fConfig = glTexDesc.fConfig;
915 
916     bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit);
917 
918     const Caps& caps = this->getCaps();
919 
920     // We keep GrRenderTargets in GL's normal orientation so that they
921     // can be drawn to by the outside world without the client having
922     // to render upside down.
923     glTexDesc.fOrientation = renderTarget ? GrGLTexture::kBottomUp_Orientation :
924                                             GrGLTexture::kTopDown_Orientation;
925 
926     glRTDesc.fSampleCnt = desc.fSampleCnt;
927     if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&
928         desc.fSampleCnt) {
929         GrPrintf("MSAA RT requested but not supported on this platform.");
930     }
931 
932     if (renderTarget) {
933         if (glTexDesc.fWidth > caps.fMaxRenderTargetSize ||
934             glTexDesc.fHeight > caps.fMaxRenderTargetSize) {
935             return return_null_texture();
936         }
937     }
938 
939     GL_CALL(GenTextures(1, &glTexDesc.fTextureID));
940     if (renderTarget && this->glCaps().textureUsageSupport()) {
941         // provides a hint about how this texture will be used
942         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
943                               GR_GL_TEXTURE_USAGE,
944                               GR_GL_FRAMEBUFFER_ATTACHMENT));
945     }
946     if (!glTexDesc.fTextureID) {
947         return return_null_texture();
948     }
949 
950     this->setSpareTextureUnit();
951     GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
952 
953     // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
954     // drivers have a bug where an FBO won't be complete if it includes a
955     // texture that is not mipmap complete (considering the filter in use).
956     GrGLTexture::TexParams initialTexParams;
957     // we only set a subset here so invalidate first
958     initialTexParams.invalidate();
959     initialTexParams.fFilter = GR_GL_NEAREST;
960     initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
961     initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
962     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
963                           GR_GL_TEXTURE_MAG_FILTER,
964                           initialTexParams.fFilter));
965     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
966                           GR_GL_TEXTURE_MIN_FILTER,
967                           initialTexParams.fFilter));
968     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
969                           GR_GL_TEXTURE_WRAP_S,
970                           initialTexParams.fWrapS));
971     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
972                           GR_GL_TEXTURE_WRAP_T,
973                           initialTexParams.fWrapT));
974     if (!this->uploadTexData(glTexDesc, true, 0, 0,
975                              glTexDesc.fWidth, glTexDesc.fHeight,
976                              desc.fConfig, srcData, rowBytes)) {
977         GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
978         return return_null_texture();
979     }
980 
981     GrGLTexture* tex;
982     if (renderTarget) {
983 #if GR_COLLECT_STATS
984         ++fStats.fRenderTargetCreateCnt;
985 #endif
986         if (!this->createRenderTargetObjects(glTexDesc.fWidth,
987                                              glTexDesc.fHeight,
988                                              glTexDesc.fTextureID,
989                                              &glRTDesc)) {
990             GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
991             return return_null_texture();
992         }
993         tex = new GrGLTexture(this, glTexDesc, glRTDesc);
994     } else {
995         tex = new GrGLTexture(this, glTexDesc);
996     }
997     tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
998 #ifdef TRACE_TEXTURE_CREATION
999     GrPrintf("--- new texture [%d] size=(%d %d) config=%d\n",
1000              glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
1001 #endif
1002     return tex;
1003 }
1004 
1005 namespace {
1006 
1007 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
1008 
get_stencil_rb_sizes(const GrGLInterface * gl,GrGLuint rb,GrGLStencilBuffer::Format * format)1009 void inline get_stencil_rb_sizes(const GrGLInterface* gl,
1010                                  GrGLuint rb,
1011                                  GrGLStencilBuffer::Format* format) {
1012     // we shouldn't ever know one size and not the other
1013     GrAssert((kUnknownBitCount == format->fStencilBits) ==
1014              (kUnknownBitCount == format->fTotalBits));
1015     if (kUnknownBitCount == format->fStencilBits) {
1016         GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1017                                          GR_GL_RENDERBUFFER_STENCIL_SIZE,
1018                                          (GrGLint*)&format->fStencilBits);
1019         if (format->fPacked) {
1020             GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1021                                              GR_GL_RENDERBUFFER_DEPTH_SIZE,
1022                                              (GrGLint*)&format->fTotalBits);
1023             format->fTotalBits += format->fStencilBits;
1024         } else {
1025             format->fTotalBits = format->fStencilBits;
1026         }
1027     }
1028 }
1029 }
1030 
createStencilBufferForRenderTarget(GrRenderTarget * rt,int width,int height)1031 bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
1032                                                  int width, int height) {
1033 
1034     // All internally created RTs are also textures. We don't create
1035     // SBs for a client's standalone RT (that is RT that isnt also a texture).
1036     GrAssert(rt->asTexture());
1037     GrAssert(width >= rt->width());
1038     GrAssert(height >= rt->height());
1039 
1040     int samples = rt->numSamples();
1041     GrGLuint sbID;
1042     GL_CALL(GenRenderbuffers(1, &sbID));
1043     if (!sbID) {
1044         return false;
1045     }
1046 
1047     GrGLStencilBuffer* sb = NULL;
1048 
1049     int stencilFmtCnt = this->glCaps().stencilFormats().count();
1050     for (int i = 0; i < stencilFmtCnt; ++i) {
1051         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID));
1052         // we start with the last stencil format that succeeded in hopes
1053         // that we won't go through this loop more than once after the
1054         // first (painful) stencil creation.
1055         int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
1056         const GrGLCaps::StencilFormat& sFmt =
1057                 this->glCaps().stencilFormats()[sIdx];
1058         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1059         // we do this "if" so that we don't call the multisample
1060         // version on a GL that doesn't have an MSAA extension.
1061         if (samples > 1) {
1062             GL_ALLOC_CALL(this->glInterface(),
1063                           RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
1064                                                          samples,
1065                                                          sFmt.fInternalFormat,
1066                                                          width, height));
1067         } else {
1068             GL_ALLOC_CALL(this->glInterface(),
1069                           RenderbufferStorage(GR_GL_RENDERBUFFER,
1070                                               sFmt.fInternalFormat,
1071                                               width, height));
1072         }
1073 
1074         GrGLenum err = CHECK_ALLOC_ERROR(this->glInterface());
1075         if (err == GR_GL_NO_ERROR) {
1076             // After sized formats we attempt an unsized format and take whatever
1077             // sizes GL gives us. In that case we query for the size.
1078             GrGLStencilBuffer::Format format = sFmt;
1079             get_stencil_rb_sizes(this->glInterface(), sbID, &format);
1080             sb = new GrGLStencilBuffer(this, sbID, width, height,
1081                                        samples, format);
1082             if (this->attachStencilBufferToRenderTarget(sb, rt)) {
1083                 fLastSuccessfulStencilFmtIdx = sIdx;
1084                 rt->setStencilBuffer(sb);
1085                 sb->unref();
1086                 return true;
1087            }
1088            sb->abandon(); // otherwise we lose sbID
1089            sb->unref();
1090         }
1091     }
1092     GL_CALL(DeleteRenderbuffers(1, &sbID));
1093     return false;
1094 }
1095 
attachStencilBufferToRenderTarget(GrStencilBuffer * sb,GrRenderTarget * rt)1096 bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
1097                                                 GrRenderTarget* rt) {
1098     GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt;
1099 
1100     GrGLuint fbo = glrt->renderFBOID();
1101 
1102     if (NULL == sb) {
1103         if (NULL != rt->getStencilBuffer()) {
1104             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1105                                           GR_GL_STENCIL_ATTACHMENT,
1106                                           GR_GL_RENDERBUFFER, 0));
1107             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1108                                           GR_GL_DEPTH_ATTACHMENT,
1109                                           GR_GL_RENDERBUFFER, 0));
1110 #if GR_DEBUG
1111             GrGLenum status;
1112             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1113             GrAssert(GR_GL_FRAMEBUFFER_COMPLETE == status);
1114 #endif
1115         }
1116         return true;
1117     } else {
1118         GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb;
1119         GrGLuint rb = glsb->renderbufferID();
1120 
1121         fHWDrawState.setRenderTarget(NULL);
1122         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
1123         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1124                                       GR_GL_STENCIL_ATTACHMENT,
1125                                       GR_GL_RENDERBUFFER, rb));
1126         if (glsb->format().fPacked) {
1127             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1128                                           GR_GL_DEPTH_ATTACHMENT,
1129                                           GR_GL_RENDERBUFFER, rb));
1130         } else {
1131             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1132                                           GR_GL_DEPTH_ATTACHMENT,
1133                                           GR_GL_RENDERBUFFER, 0));
1134         }
1135 
1136         GrGLenum status;
1137         if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
1138                                                            glsb->format())) {
1139             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1140             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
1141                 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1142                                               GR_GL_STENCIL_ATTACHMENT,
1143                                               GR_GL_RENDERBUFFER, 0));
1144                 if (glsb->format().fPacked) {
1145                     GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1146                                                   GR_GL_DEPTH_ATTACHMENT,
1147                                                   GR_GL_RENDERBUFFER, 0));
1148                 }
1149                 return false;
1150             } else {
1151                 fGLContextInfo.caps().markColorConfigAndStencilFormatAsVerified(
1152                     rt->config(),
1153                     glsb->format());
1154             }
1155         }
1156         return true;
1157     }
1158 }
1159 
1160 ////////////////////////////////////////////////////////////////////////////////
1161 
onCreateVertexBuffer(uint32_t size,bool dynamic)1162 GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) {
1163     GrGLuint id;
1164     GL_CALL(GenBuffers(1, &id));
1165     if (id) {
1166         GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, id));
1167         fHWGeometryState.fArrayPtrsDirty = true;
1168         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1169         // make sure driver can allocate memory for this buffer
1170         GL_ALLOC_CALL(this->glInterface(),
1171                       BufferData(GR_GL_ARRAY_BUFFER,
1172                                  size,
1173                                  NULL,   // data ptr
1174                                  dynamic ? GR_GL_DYNAMIC_DRAW :
1175                                            GR_GL_STATIC_DRAW));
1176         if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
1177             GL_CALL(DeleteBuffers(1, &id));
1178             // deleting bound buffer does implicit bind to 0
1179             fHWGeometryState.fVertexBuffer = NULL;
1180             return NULL;
1181         }
1182         GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, id,
1183                                                               size, dynamic);
1184         fHWGeometryState.fVertexBuffer = vertexBuffer;
1185         return vertexBuffer;
1186     }
1187     return NULL;
1188 }
1189 
onCreateIndexBuffer(uint32_t size,bool dynamic)1190 GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
1191     GrGLuint id;
1192     GL_CALL(GenBuffers(1, &id));
1193     if (id) {
1194         GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
1195         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1196         // make sure driver can allocate memory for this buffer
1197         GL_ALLOC_CALL(this->glInterface(),
1198                       BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
1199                                  size,
1200                                  NULL,  // data ptr
1201                                  dynamic ? GR_GL_DYNAMIC_DRAW :
1202                                            GR_GL_STATIC_DRAW));
1203         if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
1204             GL_CALL(DeleteBuffers(1, &id));
1205             // deleting bound buffer does implicit bind to 0
1206             fHWGeometryState.fIndexBuffer = NULL;
1207             return NULL;
1208         }
1209         GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, id,
1210                                                          size, dynamic);
1211         fHWGeometryState.fIndexBuffer = indexBuffer;
1212         return indexBuffer;
1213     }
1214     return NULL;
1215 }
1216 
flushScissor(const GrIRect * rect)1217 void GrGpuGL::flushScissor(const GrIRect* rect) {
1218     const GrDrawState& drawState = this->getDrawState();
1219     const GrGLRenderTarget* rt =
1220         static_cast<const GrGLRenderTarget*>(drawState.getRenderTarget());
1221 
1222     GrAssert(NULL != rt);
1223     const GrGLIRect& vp = rt->getViewport();
1224 
1225     GrGLIRect scissor;
1226     if (NULL != rect) {
1227         scissor.setRelativeTo(vp, rect->fLeft, rect->fTop,
1228                               rect->width(), rect->height());
1229         if (scissor.contains(vp)) {
1230             rect = NULL;
1231         }
1232     }
1233 
1234     if (NULL != rect) {
1235         if (fHWBounds.fScissorRect != scissor) {
1236             scissor.pushToGLScissor(this->glInterface());
1237             fHWBounds.fScissorRect = scissor;
1238         }
1239         if (!fHWBounds.fScissorEnabled) {
1240             GL_CALL(Enable(GR_GL_SCISSOR_TEST));
1241             fHWBounds.fScissorEnabled = true;
1242         }
1243     } else {
1244         if (fHWBounds.fScissorEnabled) {
1245             GL_CALL(Disable(GR_GL_SCISSOR_TEST));
1246             fHWBounds.fScissorEnabled = false;
1247         }
1248     }
1249 }
1250 
onClear(const GrIRect * rect,GrColor color)1251 void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
1252     const GrDrawState& drawState = this->getDrawState();
1253     const GrRenderTarget* rt = drawState.getRenderTarget();
1254     // parent class should never let us get here with no RT
1255     GrAssert(NULL != rt);
1256 
1257     GrIRect clippedRect;
1258     if (NULL != rect) {
1259         // flushScissor expects rect to be clipped to the target.
1260         clippedRect = *rect;
1261         GrIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height());
1262         if (clippedRect.intersect(rtRect)) {
1263             rect = &clippedRect;
1264         } else {
1265             return;
1266         }
1267     }
1268     this->flushRenderTarget(rect);
1269     this->flushScissor(rect);
1270 
1271     GrGLfloat r, g, b, a;
1272     static const GrGLfloat scale255 = 1.f / 255.f;
1273     a = GrColorUnpackA(color) * scale255;
1274     GrGLfloat scaleRGB = scale255;
1275     if (GrPixelConfigIsUnpremultiplied(rt->config())) {
1276         scaleRGB *= a;
1277     }
1278     r = GrColorUnpackR(color) * scaleRGB;
1279     g = GrColorUnpackG(color) * scaleRGB;
1280     b = GrColorUnpackB(color) * scaleRGB;
1281 
1282     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
1283     fHWDrawState.disableState(GrDrawState::kNoColorWrites_StateBit);
1284     GL_CALL(ClearColor(r, g, b, a));
1285     GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
1286 }
1287 
clearStencil()1288 void GrGpuGL::clearStencil() {
1289     if (NULL == this->getDrawState().getRenderTarget()) {
1290         return;
1291     }
1292 
1293     this->flushRenderTarget(&GrIRect::EmptyIRect());
1294 
1295     if (fHWBounds.fScissorEnabled) {
1296         GL_CALL(Disable(GR_GL_SCISSOR_TEST));
1297         fHWBounds.fScissorEnabled = false;
1298     }
1299     GL_CALL(StencilMask(0xffffffff));
1300     GL_CALL(ClearStencil(0));
1301     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
1302     fHWDrawState.stencil()->invalidate();
1303 }
1304 
clearStencilClip(const GrIRect & rect,bool insideClip)1305 void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
1306     const GrDrawState& drawState = this->getDrawState();
1307     const GrRenderTarget* rt = drawState.getRenderTarget();
1308     GrAssert(NULL != rt);
1309 
1310     // this should only be called internally when we know we have a
1311     // stencil buffer.
1312     GrAssert(NULL != rt->getStencilBuffer());
1313     GrGLint stencilBitCount =  rt->getStencilBuffer()->bits();
1314 #if 0
1315     GrAssert(stencilBitCount > 0);
1316     GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
1317 #else
1318     // we could just clear the clip bit but when we go through
1319     // ANGLE a partial stencil mask will cause clears to be
1320     // turned into draws. Our contract on GrDrawTarget says that
1321     // changing the clip between stencil passes may or may not
1322     // zero the client's clip bits. So we just clear the whole thing.
1323     static const GrGLint clipStencilMask  = ~0;
1324 #endif
1325     GrGLint value;
1326     if (insideClip) {
1327         value = (1 << (stencilBitCount - 1));
1328     } else {
1329         value = 0;
1330     }
1331     this->flushRenderTarget(&GrIRect::EmptyIRect());
1332     this->flushScissor(&rect);
1333     GL_CALL(StencilMask(clipStencilMask));
1334     GL_CALL(ClearStencil(value));
1335     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
1336     fHWDrawState.stencil()->invalidate();
1337 }
1338 
onForceRenderTargetFlush()1339 void GrGpuGL::onForceRenderTargetFlush() {
1340     this->flushRenderTarget(&GrIRect::EmptyIRect());
1341 }
1342 
readPixelsWillPayForYFlip(GrRenderTarget * renderTarget,int left,int top,int width,int height,GrPixelConfig config,size_t rowBytes) const1343 bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
1344                                         int left, int top,
1345                                         int width, int height,
1346                                         GrPixelConfig config,
1347                                         size_t rowBytes) const {
1348     // if GL can do the flip then we'll never pay for it.
1349     if (this->glCaps().packFlipYSupport()) {
1350         return false;
1351     }
1352 
1353     // If we have to do memcpy to handle non-trim rowBytes then we
1354     // get the flip for free. Otherwise it costs.
1355     if (this->glCaps().packRowLengthSupport()) {
1356         return true;
1357     }
1358     // If we have to do memcpys to handle rowBytes then y-flip is free
1359     // Note the rowBytes might be tight to the passed in data, but if data
1360     // gets clipped in x to the target the rowBytes will no longer be tight.
1361     if (left >= 0 && (left + width) < renderTarget->width()) {
1362            return 0 == rowBytes ||
1363                   GrBytesPerPixel(config) * width == rowBytes;
1364     } else {
1365         return false;
1366     }
1367 }
1368 
onReadPixels(GrRenderTarget * target,int left,int top,int width,int height,GrPixelConfig config,void * buffer,size_t rowBytes,bool invertY)1369 bool GrGpuGL::onReadPixels(GrRenderTarget* target,
1370                            int left, int top,
1371                            int width, int height,
1372                            GrPixelConfig config,
1373                            void* buffer,
1374                            size_t rowBytes,
1375                            bool invertY) {
1376     GrGLenum format;
1377     GrGLenum type;
1378     if (!this->configToGLFormats(config, false, NULL, &format, &type)) {
1379         return false;
1380     }
1381     size_t bpp = GrBytesPerPixel(config);
1382     if (!adjust_pixel_ops_params(target->width(), target->height(), bpp,
1383                                  &left, &top, &width, &height,
1384                                  const_cast<const void**>(&buffer),
1385                                  &rowBytes)) {
1386         return false;
1387     }
1388 
1389     // resolve the render target if necessary
1390     GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
1391     GrDrawState::AutoRenderTargetRestore artr;
1392     switch (tgt->getResolveType()) {
1393         case GrGLRenderTarget::kCantResolve_ResolveType:
1394             return false;
1395         case GrGLRenderTarget::kAutoResolves_ResolveType:
1396             artr.set(this->drawState(), target);
1397             this->flushRenderTarget(&GrIRect::EmptyIRect());
1398             break;
1399         case GrGLRenderTarget::kCanResolve_ResolveType:
1400             this->onResolveRenderTarget(tgt);
1401             // we don't track the state of the READ FBO ID.
1402             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
1403                                     tgt->textureFBOID()));
1404             break;
1405         default:
1406             GrCrash("Unknown resolve type");
1407     }
1408 
1409     const GrGLIRect& glvp = tgt->getViewport();
1410 
1411     // the read rect is viewport-relative
1412     GrGLIRect readRect;
1413     readRect.setRelativeTo(glvp, left, top, width, height);
1414 
1415     size_t tightRowBytes = bpp * width;
1416     if (0 == rowBytes) {
1417         rowBytes = tightRowBytes;
1418     }
1419     size_t readDstRowBytes = tightRowBytes;
1420     void* readDst = buffer;
1421 
1422     // determine if GL can read using the passed rowBytes or if we need
1423     // a scratch buffer.
1424     SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
1425     if (rowBytes != tightRowBytes) {
1426         if (this->glCaps().packRowLengthSupport()) {
1427             GrAssert(!(rowBytes % sizeof(GrColor)));
1428             GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowBytes / sizeof(GrColor)));
1429             readDstRowBytes = rowBytes;
1430         } else {
1431             scratch.reset(tightRowBytes * height);
1432             readDst = scratch.get();
1433         }
1434     }
1435     if (!invertY && this->glCaps().packFlipYSupport()) {
1436         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1));
1437     }
1438     GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
1439                        readRect.fWidth, readRect.fHeight,
1440                        format, type, readDst));
1441     if (readDstRowBytes != tightRowBytes) {
1442         GrAssert(this->glCaps().packRowLengthSupport());
1443         GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
1444     }
1445     if (!invertY && this->glCaps().packFlipYSupport()) {
1446         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0));
1447         invertY = true;
1448     }
1449 
1450     // now reverse the order of the rows, since GL's are bottom-to-top, but our
1451     // API presents top-to-bottom. We must preserve the padding contents. Note
1452     // that the above readPixels did not overwrite the padding.
1453     if (readDst == buffer) {
1454         GrAssert(rowBytes == readDstRowBytes);
1455         if (!invertY) {
1456             scratch.reset(tightRowBytes);
1457             void* tmpRow = scratch.get();
1458             // flip y in-place by rows
1459             const int halfY = height >> 1;
1460             char* top = reinterpret_cast<char*>(buffer);
1461             char* bottom = top + (height - 1) * rowBytes;
1462             for (int y = 0; y < halfY; y++) {
1463                 memcpy(tmpRow, top, tightRowBytes);
1464                 memcpy(top, bottom, tightRowBytes);
1465                 memcpy(bottom, tmpRow, tightRowBytes);
1466                 top += rowBytes;
1467                 bottom -= rowBytes;
1468             }
1469         }
1470     } else {
1471         GrAssert(readDst != buffer);        GrAssert(rowBytes != tightRowBytes);
1472         // copy from readDst to buffer while flipping y
1473         const int halfY = height >> 1;
1474         const char* src = reinterpret_cast<const char*>(readDst);
1475         char* dst = reinterpret_cast<char*>(buffer);
1476         if (!invertY) {
1477             dst += (height-1) * rowBytes;
1478         }
1479         for (int y = 0; y < height; y++) {
1480             memcpy(dst, src, tightRowBytes);
1481             src += readDstRowBytes;
1482             if (invertY) {
1483                 dst += rowBytes;
1484             } else {
1485                 dst -= rowBytes;
1486             }
1487         }
1488     }
1489     return true;
1490 }
1491 
flushRenderTarget(const GrIRect * bound)1492 void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
1493 
1494     GrGLRenderTarget* rt =
1495         static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget());
1496     GrAssert(NULL != rt);
1497 
1498     if (fHWDrawState.getRenderTarget() != rt) {
1499         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID()));
1500     #if GR_COLLECT_STATS
1501         ++fStats.fRenderTargetChngCnt;
1502     #endif
1503     #if GR_DEBUG
1504         GrGLenum status;
1505         GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1506         if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
1507             GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status);
1508         }
1509     #endif
1510         fDirtyFlags.fRenderTargetChanged = true;
1511         fHWDrawState.setRenderTarget(rt);
1512         const GrGLIRect& vp = rt->getViewport();
1513         if (fHWBounds.fViewportRect != vp) {
1514             vp.pushToGLViewport(this->glInterface());
1515             fHWBounds.fViewportRect = vp;
1516         }
1517     }
1518     if (NULL == bound || !bound->isEmpty()) {
1519         rt->flagAsNeedingResolve(bound);
1520     }
1521 }
1522 
1523 GrGLenum gPrimitiveType2GLMode[] = {
1524     GR_GL_TRIANGLES,
1525     GR_GL_TRIANGLE_STRIP,
1526     GR_GL_TRIANGLE_FAN,
1527     GR_GL_POINTS,
1528     GR_GL_LINES,
1529     GR_GL_LINE_STRIP
1530 };
1531 
1532 #define SWAP_PER_DRAW 0
1533 
1534 #if SWAP_PER_DRAW
1535     #if GR_MAC_BUILD
1536         #include <AGL/agl.h>
1537     #elif GR_WIN32_BUILD
SwapBuf()1538         void SwapBuf() {
1539             DWORD procID = GetCurrentProcessId();
1540             HWND hwnd = GetTopWindow(GetDesktopWindow());
1541             while(hwnd) {
1542                 DWORD wndProcID = 0;
1543                 GetWindowThreadProcessId(hwnd, &wndProcID);
1544                 if(wndProcID == procID) {
1545                     SwapBuffers(GetDC(hwnd));
1546                 }
1547                 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
1548             }
1549          }
1550     #endif
1551 #endif
1552 
onGpuDrawIndexed(GrPrimitiveType type,uint32_t startVertex,uint32_t startIndex,uint32_t vertexCount,uint32_t indexCount)1553 void GrGpuGL::onGpuDrawIndexed(GrPrimitiveType type,
1554                                uint32_t startVertex,
1555                                uint32_t startIndex,
1556                                uint32_t vertexCount,
1557                                uint32_t indexCount) {
1558     GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
1559 
1560     GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * startIndex);
1561 
1562     GrAssert(NULL != fHWGeometryState.fIndexBuffer);
1563     GrAssert(NULL != fHWGeometryState.fVertexBuffer);
1564 
1565     // our setupGeometry better have adjusted this to zero since
1566     // DrawElements always draws from the begining of the arrays for idx 0.
1567     GrAssert(0 == startVertex);
1568 
1569     GL_CALL(DrawElements(gPrimitiveType2GLMode[type], indexCount,
1570                          GR_GL_UNSIGNED_SHORT, indices));
1571 #if SWAP_PER_DRAW
1572     glFlush();
1573     #if GR_MAC_BUILD
1574         aglSwapBuffers(aglGetCurrentContext());
1575         int set_a_break_pt_here = 9;
1576         aglSwapBuffers(aglGetCurrentContext());
1577     #elif GR_WIN32_BUILD
1578         SwapBuf();
1579         int set_a_break_pt_here = 9;
1580         SwapBuf();
1581     #endif
1582 #endif
1583 }
1584 
onGpuDrawNonIndexed(GrPrimitiveType type,uint32_t startVertex,uint32_t vertexCount)1585 void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
1586                                   uint32_t startVertex,
1587                                   uint32_t vertexCount) {
1588     GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
1589 
1590     GrAssert(NULL != fHWGeometryState.fVertexBuffer);
1591 
1592     // our setupGeometry better have adjusted this to zero.
1593     // DrawElements doesn't take an offset so we always adjus the startVertex.
1594     GrAssert(0 == startVertex);
1595 
1596     // pass 0 for parameter first. We have to adjust gl*Pointer() to
1597     // account for startVertex in the DrawElements case. So we always
1598     // rely on setupGeometry to have accounted for startVertex.
1599     GL_CALL(DrawArrays(gPrimitiveType2GLMode[type], 0, vertexCount));
1600 #if SWAP_PER_DRAW
1601     glFlush();
1602     #if GR_MAC_BUILD
1603         aglSwapBuffers(aglGetCurrentContext());
1604         int set_a_break_pt_here = 9;
1605         aglSwapBuffers(aglGetCurrentContext());
1606     #elif GR_WIN32_BUILD
1607         SwapBuf();
1608         int set_a_break_pt_here = 9;
1609         SwapBuf();
1610     #endif
1611 #endif
1612 }
1613 
onResolveRenderTarget(GrRenderTarget * target)1614 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
1615 
1616     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
1617 
1618     if (rt->needsResolve()) {
1619         GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType());
1620         GrAssert(rt->textureFBOID() != rt->renderFBOID());
1621         GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
1622                                 rt->renderFBOID()));
1623         GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER,
1624                                 rt->textureFBOID()));
1625     #if GR_COLLECT_STATS
1626         ++fStats.fRenderTargetChngCnt;
1627     #endif
1628         // make sure we go through flushRenderTarget() since we've modified
1629         // the bound DRAW FBO ID.
1630         fHWDrawState.setRenderTarget(NULL);
1631         const GrGLIRect& vp = rt->getViewport();
1632         const GrIRect dirtyRect = rt->getResolveRect();
1633         GrGLIRect r;
1634         r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
1635                         dirtyRect.width(), dirtyRect.height());
1636 
1637         if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
1638             // Apple's extension uses the scissor as the blit bounds.
1639             GL_CALL(Enable(GR_GL_SCISSOR_TEST));
1640             GL_CALL(Scissor(r.fLeft, r.fBottom,
1641                             r.fWidth, r.fHeight));
1642             GL_CALL(ResolveMultisampleFramebuffer());
1643             fHWBounds.fScissorRect.invalidate();
1644             fHWBounds.fScissorEnabled = true;
1645         } else {
1646             if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
1647                 // this respects the scissor during the blit, so disable it.
1648                 GrAssert(GrGLCaps::kDesktopEXT_MSFBOType ==
1649                          this->glCaps().msFBOType());
1650                 this->flushScissor(NULL);
1651             }
1652             int right = r.fLeft + r.fWidth;
1653             int top = r.fBottom + r.fHeight;
1654             GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
1655                                     r.fLeft, r.fBottom, right, top,
1656                                     GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
1657         }
1658         rt->flagAsResolved();
1659     }
1660 }
1661 
1662 static const GrGLenum grToGLStencilFunc[] = {
1663     GR_GL_ALWAYS,           // kAlways_StencilFunc
1664     GR_GL_NEVER,            // kNever_StencilFunc
1665     GR_GL_GREATER,          // kGreater_StencilFunc
1666     GR_GL_GEQUAL,           // kGEqual_StencilFunc
1667     GR_GL_LESS,             // kLess_StencilFunc
1668     GR_GL_LEQUAL,           // kLEqual_StencilFunc,
1669     GR_GL_EQUAL,            // kEqual_StencilFunc,
1670     GR_GL_NOTEQUAL,         // kNotEqual_StencilFunc,
1671 };
1672 GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilFunc) == kBasicStencilFuncCount);
1673 GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
1674 GR_STATIC_ASSERT(1 == kNever_StencilFunc);
1675 GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
1676 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
1677 GR_STATIC_ASSERT(4 == kLess_StencilFunc);
1678 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
1679 GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
1680 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
1681 
1682 static const GrGLenum grToGLStencilOp[] = {
1683     GR_GL_KEEP,        // kKeep_StencilOp
1684     GR_GL_REPLACE,     // kReplace_StencilOp
1685     GR_GL_INCR_WRAP,   // kIncWrap_StencilOp
1686     GR_GL_INCR,        // kIncClamp_StencilOp
1687     GR_GL_DECR_WRAP,   // kDecWrap_StencilOp
1688     GR_GL_DECR,        // kDecClamp_StencilOp
1689     GR_GL_ZERO,        // kZero_StencilOp
1690     GR_GL_INVERT,      // kInvert_StencilOp
1691 };
1692 GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilOp) == kStencilOpCount);
1693 GR_STATIC_ASSERT(0 == kKeep_StencilOp);
1694 GR_STATIC_ASSERT(1 == kReplace_StencilOp);
1695 GR_STATIC_ASSERT(2 == kIncWrap_StencilOp);
1696 GR_STATIC_ASSERT(3 == kIncClamp_StencilOp);
1697 GR_STATIC_ASSERT(4 == kDecWrap_StencilOp);
1698 GR_STATIC_ASSERT(5 == kDecClamp_StencilOp);
1699 GR_STATIC_ASSERT(6 == kZero_StencilOp);
1700 GR_STATIC_ASSERT(7 == kInvert_StencilOp);
1701 
flushStencil()1702 void GrGpuGL::flushStencil() {
1703     const GrDrawState& drawState = this->getDrawState();
1704 
1705     const GrStencilSettings* settings = &drawState.getStencil();
1706 
1707     // use stencil for clipping if clipping is enabled and the clip
1708     // has been written into the stencil.
1709     bool stencilClip = fClipInStencil && drawState.isClipState();
1710     bool drawClipToStencil =
1711         drawState.isStateFlagEnabled(kModifyStencilClip_StateBit);
1712     bool stencilChange = (fHWDrawState.getStencil() != *settings) ||
1713                          (fHWStencilClip != stencilClip) ||
1714                          (fHWDrawState.isStateFlagEnabled(kModifyStencilClip_StateBit) !=
1715                           drawClipToStencil);
1716 
1717     if (stencilChange) {
1718 
1719         // we can't simultaneously perform stencil-clipping and
1720         // modify the stencil clip
1721         GrAssert(!stencilClip || !drawClipToStencil);
1722 
1723         if (settings->isDisabled()) {
1724             if (stencilClip) {
1725                 settings = GetClipStencilSettings();
1726             }
1727         }
1728 
1729         if (settings->isDisabled()) {
1730             GL_CALL(Disable(GR_GL_STENCIL_TEST));
1731         } else {
1732             GL_CALL(Enable(GR_GL_STENCIL_TEST));
1733     #if GR_DEBUG
1734             if (!this->getCaps().fStencilWrapOpsSupport) {
1735                 GrAssert(settings->frontPassOp() != kIncWrap_StencilOp);
1736                 GrAssert(settings->frontPassOp() != kDecWrap_StencilOp);
1737                 GrAssert(settings->frontFailOp() != kIncWrap_StencilOp);
1738                 GrAssert(settings->backFailOp() != kDecWrap_StencilOp);
1739                 GrAssert(settings->backPassOp() != kIncWrap_StencilOp);
1740                 GrAssert(settings->backPassOp() != kDecWrap_StencilOp);
1741                 GrAssert(settings->backFailOp() != kIncWrap_StencilOp);
1742                 GrAssert(settings->frontFailOp() != kDecWrap_StencilOp);
1743             }
1744     #endif
1745             int stencilBits = 0;
1746             GrStencilBuffer* stencilBuffer =
1747                 drawState.getRenderTarget()->getStencilBuffer();
1748             if (NULL != stencilBuffer) {
1749                 stencilBits = stencilBuffer->bits();
1750             }
1751             // TODO: dynamically attach a stencil buffer
1752             GrAssert(stencilBits || settings->isDisabled());
1753 
1754             GrGLuint clipStencilMask = 0;
1755             GrGLuint userStencilMask = ~0;
1756             if (stencilBits > 0) {
1757                 clipStencilMask =  1 << (stencilBits - 1);
1758                 userStencilMask = clipStencilMask - 1;
1759             }
1760 
1761             unsigned int frontRef  = settings->frontFuncRef();
1762             unsigned int frontMask = settings->frontFuncMask();
1763             unsigned int frontWriteMask = settings->frontWriteMask();
1764             GrGLenum frontFunc;
1765 
1766             if (drawClipToStencil) {
1767                 GrAssert(settings->frontFunc() < kBasicStencilFuncCount);
1768                 frontFunc = grToGLStencilFunc[settings->frontFunc()];
1769             } else {
1770                 frontFunc = grToGLStencilFunc[ConvertStencilFunc(
1771                         stencilClip, settings->frontFunc())];
1772 
1773                 ConvertStencilFuncAndMask(settings->frontFunc(),
1774                                           stencilClip,
1775                                           clipStencilMask,
1776                                           userStencilMask,
1777                                           &frontRef,
1778                                           &frontMask);
1779                 frontWriteMask &= userStencilMask;
1780             }
1781             GrAssert((size_t)
1782                 settings->frontFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
1783             GrAssert((size_t)
1784                 settings->frontPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
1785             GrAssert((size_t)
1786                 settings->backFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
1787             GrAssert((size_t)
1788                 settings->backPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
1789             if (this->getCaps().fTwoSidedStencilSupport) {
1790                 GrGLenum backFunc;
1791 
1792                 unsigned int backRef  = settings->backFuncRef();
1793                 unsigned int backMask = settings->backFuncMask();
1794                 unsigned int backWriteMask = settings->backWriteMask();
1795 
1796 
1797                 if (drawClipToStencil) {
1798                     GrAssert(settings->backFunc() < kBasicStencilFuncCount);
1799                     backFunc = grToGLStencilFunc[settings->backFunc()];
1800                 } else {
1801                     backFunc = grToGLStencilFunc[ConvertStencilFunc(
1802                         stencilClip, settings->backFunc())];
1803                     ConvertStencilFuncAndMask(settings->backFunc(),
1804                                               stencilClip,
1805                                               clipStencilMask,
1806                                               userStencilMask,
1807                                               &backRef,
1808                                               &backMask);
1809                     backWriteMask &= userStencilMask;
1810                 }
1811 
1812                 GL_CALL(StencilFuncSeparate(GR_GL_FRONT, frontFunc,
1813                                             frontRef, frontMask));
1814                 GL_CALL(StencilMaskSeparate(GR_GL_FRONT, frontWriteMask));
1815                 GL_CALL(StencilFuncSeparate(GR_GL_BACK, backFunc,
1816                                             backRef, backMask));
1817                 GL_CALL(StencilMaskSeparate(GR_GL_BACK, backWriteMask));
1818                 GL_CALL(StencilOpSeparate(GR_GL_FRONT,
1819                                     grToGLStencilOp[settings->frontFailOp()],
1820                                     grToGLStencilOp[settings->frontPassOp()],
1821                                     grToGLStencilOp[settings->frontPassOp()]));
1822 
1823                 GL_CALL(StencilOpSeparate(GR_GL_BACK,
1824                                     grToGLStencilOp[settings->backFailOp()],
1825                                     grToGLStencilOp[settings->backPassOp()],
1826                                     grToGLStencilOp[settings->backPassOp()]));
1827             } else {
1828                 GL_CALL(StencilFunc(frontFunc, frontRef, frontMask));
1829                 GL_CALL(StencilMask(frontWriteMask));
1830                 GL_CALL(StencilOp(grToGLStencilOp[settings->frontFailOp()],
1831                                 grToGLStencilOp[settings->frontPassOp()],
1832                                 grToGLStencilOp[settings->frontPassOp()]));
1833             }
1834         }
1835         *fHWDrawState.stencil() = *settings;
1836         fHWStencilClip = stencilClip;
1837     }
1838 }
1839 
flushAAState(GrPrimitiveType type)1840 void GrGpuGL::flushAAState(GrPrimitiveType type) {
1841     const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
1842     if (kDesktop_GrGLBinding == this->glBinding()) {
1843         // ES doesn't support toggling GL_MULTISAMPLE and doesn't have
1844         // smooth lines.
1845 
1846         // we prefer smooth lines over multisampled lines
1847         // msaa should be disabled if drawing smooth lines.
1848         if (GrIsPrimTypeLines(type)) {
1849             bool smooth = this->willUseHWAALines();
1850             if (!fHWAAState.fSmoothLineEnabled && smooth) {
1851                 GL_CALL(Enable(GR_GL_LINE_SMOOTH));
1852                 fHWAAState.fSmoothLineEnabled = true;
1853             } else if (fHWAAState.fSmoothLineEnabled && !smooth) {
1854                 GL_CALL(Disable(GR_GL_LINE_SMOOTH));
1855                 fHWAAState.fSmoothLineEnabled = false;
1856             }
1857             if (rt->isMultisampled() &&
1858                 fHWAAState.fMSAAEnabled) {
1859                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
1860                 fHWAAState.fMSAAEnabled = false;
1861             }
1862         } else if (rt->isMultisampled() &&
1863                    this->getDrawState().isHWAntialiasState() !=
1864                    fHWAAState.fMSAAEnabled) {
1865             if (fHWAAState.fMSAAEnabled) {
1866                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
1867                 fHWAAState.fMSAAEnabled = false;
1868             } else {
1869                 GL_CALL(Enable(GR_GL_MULTISAMPLE));
1870                 fHWAAState.fMSAAEnabled = true;
1871             }
1872         }
1873     }
1874 }
1875 
flushBlend(GrPrimitiveType type,GrBlendCoeff srcCoeff,GrBlendCoeff dstCoeff)1876 void GrGpuGL::flushBlend(GrPrimitiveType type,
1877                          GrBlendCoeff srcCoeff,
1878                          GrBlendCoeff dstCoeff) {
1879     if (GrIsPrimTypeLines(type) && this->willUseHWAALines()) {
1880         if (fHWBlendDisabled) {
1881             GL_CALL(Enable(GR_GL_BLEND));
1882             fHWBlendDisabled = false;
1883         }
1884         if (kSA_BlendCoeff != fHWDrawState.getSrcBlendCoeff() ||
1885             kISA_BlendCoeff != fHWDrawState.getDstBlendCoeff()) {
1886             GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_BlendCoeff],
1887                               gXfermodeCoeff2Blend[kISA_BlendCoeff]));
1888             fHWDrawState.setBlendFunc(kSA_BlendCoeff, kISA_BlendCoeff);
1889         }
1890     } else {
1891         // any optimization to disable blending should
1892         // have already been applied and tweaked the coeffs
1893         // to (1, 0).
1894         bool blendOff = kOne_BlendCoeff == srcCoeff &&
1895                         kZero_BlendCoeff == dstCoeff;
1896         if (fHWBlendDisabled != blendOff) {
1897             if (blendOff) {
1898                 GL_CALL(Disable(GR_GL_BLEND));
1899             } else {
1900                 GL_CALL(Enable(GR_GL_BLEND));
1901             }
1902             fHWBlendDisabled = blendOff;
1903         }
1904         if (!blendOff) {
1905             if (fHWDrawState.getSrcBlendCoeff() != srcCoeff ||
1906                 fHWDrawState.getDstBlendCoeff() != dstCoeff) {
1907                 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
1908                                   gXfermodeCoeff2Blend[dstCoeff]));
1909                 fHWDrawState.setBlendFunc(srcCoeff, dstCoeff);
1910             }
1911             GrColor blendConst = fCurrDrawState.getBlendConstant();
1912             if ((BlendCoeffReferencesConstant(srcCoeff) ||
1913                  BlendCoeffReferencesConstant(dstCoeff)) &&
1914                 fHWDrawState.getBlendConstant() != blendConst) {
1915 
1916                 float c[] = {
1917                     GrColorUnpackR(blendConst) / 255.f,
1918                     GrColorUnpackG(blendConst) / 255.f,
1919                     GrColorUnpackB(blendConst) / 255.f,
1920                     GrColorUnpackA(blendConst) / 255.f
1921                 };
1922                 GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
1923                 fHWDrawState.setBlendConstant(blendConst);
1924             }
1925         }
1926     }
1927 }
1928 
1929 namespace {
1930 
gr_to_gl_filter(GrSamplerState::Filter filter)1931 unsigned gr_to_gl_filter(GrSamplerState::Filter filter) {
1932     switch (filter) {
1933         case GrSamplerState::kBilinear_Filter:
1934         case GrSamplerState::k4x4Downsample_Filter:
1935             return GR_GL_LINEAR;
1936         case GrSamplerState::kNearest_Filter:
1937         case GrSamplerState::kConvolution_Filter:
1938         case GrSamplerState::kErode_Filter:
1939         case GrSamplerState::kDilate_Filter:
1940             return GR_GL_NEAREST;
1941         default:
1942             GrAssert(!"Unknown filter type");
1943             return GR_GL_LINEAR;
1944     }
1945 }
1946 
get_swizzle(GrPixelConfig config,const GrSamplerState & sampler)1947 const GrGLenum* get_swizzle(GrPixelConfig config,
1948                             const GrSamplerState& sampler) {
1949     if (GrPixelConfigIsAlphaOnly(config)) {
1950         static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
1951                                                 GR_GL_ALPHA, GR_GL_ALPHA };
1952         return gAlphaSmear;
1953     } else if (sampler.swapsRAndB()) {
1954         static const GrGLenum gRedBlueSwap[] = { GR_GL_BLUE, GR_GL_GREEN,
1955                                                  GR_GL_RED,  GR_GL_ALPHA };
1956         return gRedBlueSwap;
1957     } else {
1958         static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN,
1959                                               GR_GL_BLUE,  GR_GL_ALPHA };
1960         return gStraight;
1961     }
1962 }
1963 
set_tex_swizzle(GrGLenum swizzle[4],const GrGLInterface * gl)1964 void set_tex_swizzle(GrGLenum swizzle[4], const GrGLInterface* gl) {
1965     // should add texparameteri to interface to make 1 instead of 4 calls here
1966     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
1967                                  GR_GL_TEXTURE_SWIZZLE_R,
1968                                  swizzle[0]));
1969     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
1970                                  GR_GL_TEXTURE_SWIZZLE_G,
1971                                  swizzle[1]));
1972     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
1973                                  GR_GL_TEXTURE_SWIZZLE_B,
1974                                  swizzle[2]));
1975     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
1976                                  GR_GL_TEXTURE_SWIZZLE_A,
1977                                  swizzle[3]));
1978 }
1979 }
1980 
flushGLStateCommon(GrPrimitiveType type)1981 bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
1982 
1983     GrDrawState* drawState = this->drawState();
1984     // GrGpu::setupClipAndFlushState should have already checked this
1985     // and bailed if not true.
1986     GrAssert(NULL != drawState->getRenderTarget());
1987 
1988     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
1989         // bind texture and set sampler state
1990         if (this->isStageEnabled(s)) {
1991             GrGLTexture* nextTexture =
1992                 static_cast<GrGLTexture*>(drawState->getTexture(s));
1993 
1994             // true for now, but maybe not with GrEffect.
1995             GrAssert(NULL != nextTexture);
1996             // if we created a rt/tex and rendered to it without using a
1997             // texture and now we're texuring from the rt it will still be
1998             // the last bound texture, but it needs resolving. So keep this
1999             // out of the "last != next" check.
2000             GrGLRenderTarget* texRT =
2001                 static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
2002             if (NULL != texRT) {
2003                 this->onResolveRenderTarget(texRT);
2004             }
2005 
2006             if (fHWDrawState.getTexture(s) != nextTexture) {
2007                 setTextureUnit(s);
2008                 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID()));
2009             #if GR_COLLECT_STATS
2010                 ++fStats.fTextureChngCnt;
2011             #endif
2012                 //GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
2013                 fHWDrawState.setTexture(s, nextTexture);
2014                 // The texture matrix has to compensate for texture width/height
2015                 // and NPOT-embedded-in-POT
2016                 fDirtyFlags.fTextureChangedMask |= (1 << s);
2017             }
2018 
2019             const GrSamplerState& sampler = drawState->getSampler(s);
2020             ResetTimestamp timestamp;
2021             const GrGLTexture::TexParams& oldTexParams =
2022                                     nextTexture->getCachedTexParams(&timestamp);
2023             bool setAll = timestamp < this->getResetTimestamp();
2024             GrGLTexture::TexParams newTexParams;
2025 
2026             newTexParams.fFilter = gr_to_gl_filter(sampler.getFilter());
2027 
2028             const GrGLenum* wraps =  GrGLTexture::WrapMode2GLWrap();
2029             newTexParams.fWrapS = wraps[sampler.getWrapX()];
2030             newTexParams.fWrapT = wraps[sampler.getWrapY()];
2031             memcpy(newTexParams.fSwizzleRGBA,
2032                    get_swizzle(nextTexture->config(), sampler),
2033                    sizeof(newTexParams.fSwizzleRGBA));
2034             if (setAll || newTexParams.fFilter != oldTexParams.fFilter) {
2035                 setTextureUnit(s);
2036                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2037                                         GR_GL_TEXTURE_MAG_FILTER,
2038                                         newTexParams.fFilter));
2039                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2040                                         GR_GL_TEXTURE_MIN_FILTER,
2041                                         newTexParams.fFilter));
2042             }
2043             if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
2044                 setTextureUnit(s);
2045                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2046                                         GR_GL_TEXTURE_WRAP_S,
2047                                         newTexParams.fWrapS));
2048             }
2049             if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
2050                 setTextureUnit(s);
2051                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2052                                         GR_GL_TEXTURE_WRAP_T,
2053                                         newTexParams.fWrapT));
2054             }
2055             if (this->glCaps().textureSwizzleSupport() &&
2056                 (setAll ||
2057                  memcmp(newTexParams.fSwizzleRGBA,
2058                         oldTexParams.fSwizzleRGBA,
2059                         sizeof(newTexParams.fSwizzleRGBA)))) {
2060                 setTextureUnit(s);
2061                 set_tex_swizzle(newTexParams.fSwizzleRGBA,
2062                                 this->glInterface());
2063             }
2064             nextTexture->setCachedTexParams(newTexParams,
2065                                             this->getResetTimestamp());
2066         }
2067     }
2068 
2069     GrIRect* rect = NULL;
2070     GrIRect clipBounds;
2071     if (drawState->isClipState() &&
2072         fClip.hasConservativeBounds()) {
2073         fClip.getConservativeBounds().roundOut(&clipBounds);
2074         rect = &clipBounds;
2075     }
2076     this->flushRenderTarget(rect);
2077     this->flushAAState(type);
2078 
2079     if (drawState->isDitherState() != fHWDrawState.isDitherState()) {
2080         if (drawState->isDitherState()) {
2081             GL_CALL(Enable(GR_GL_DITHER));
2082         } else {
2083             GL_CALL(Disable(GR_GL_DITHER));
2084         }
2085     }
2086 
2087     if (drawState->isColorWriteDisabled() !=
2088         fHWDrawState.isColorWriteDisabled()) {
2089         GrGLenum mask;
2090         if (drawState->isColorWriteDisabled()) {
2091             mask = GR_GL_FALSE;
2092         } else {
2093             mask = GR_GL_TRUE;
2094         }
2095         GL_CALL(ColorMask(mask, mask, mask, mask));
2096     }
2097 
2098     if (fHWDrawState.getDrawFace() != drawState->getDrawFace()) {
2099         switch (fCurrDrawState.getDrawFace()) {
2100             case GrDrawState::kCCW_DrawFace:
2101                 GL_CALL(Enable(GR_GL_CULL_FACE));
2102                 GL_CALL(CullFace(GR_GL_BACK));
2103                 break;
2104             case GrDrawState::kCW_DrawFace:
2105                 GL_CALL(Enable(GR_GL_CULL_FACE));
2106                 GL_CALL(CullFace(GR_GL_FRONT));
2107                 break;
2108             case GrDrawState::kBoth_DrawFace:
2109                 GL_CALL(Disable(GR_GL_CULL_FACE));
2110                 break;
2111             default:
2112                 GrCrash("Unknown draw face.");
2113         }
2114         fHWDrawState.setDrawFace(drawState->getDrawFace());
2115     }
2116 
2117 #if GR_DEBUG
2118     // check for circular rendering
2119     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
2120         GrAssert(!this->isStageEnabled(s) ||
2121                  NULL == drawState->getRenderTarget() ||
2122                  NULL == drawState->getTexture(s) ||
2123                  drawState->getTexture(s)->asRenderTarget() !=
2124                     drawState->getRenderTarget());
2125     }
2126 #endif
2127 
2128     this->flushStencil();
2129 
2130     // This copy must happen after flushStencil() is called. flushStencil()
2131     // relies on detecting when the kModifyStencilClip_StateBit state has
2132     // changed since the last draw.
2133     fHWDrawState.copyStateFlags(*drawState);
2134     return true;
2135 }
2136 
notifyVertexBufferBind(const GrGLVertexBuffer * buffer)2137 void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) {
2138     if (fHWGeometryState.fVertexBuffer != buffer) {
2139         fHWGeometryState.fArrayPtrsDirty = true;
2140         fHWGeometryState.fVertexBuffer = buffer;
2141     }
2142 }
2143 
notifyVertexBufferDelete(const GrGLVertexBuffer * buffer)2144 void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) {
2145     if (fHWGeometryState.fVertexBuffer == buffer) {
2146         // deleting bound buffer does implied bind to 0
2147         fHWGeometryState.fVertexBuffer = NULL;
2148         fHWGeometryState.fArrayPtrsDirty = true;
2149     }
2150 }
2151 
notifyIndexBufferBind(const GrGLIndexBuffer * buffer)2152 void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
2153     fHWGeometryState.fIndexBuffer = buffer;
2154 }
2155 
notifyIndexBufferDelete(const GrGLIndexBuffer * buffer)2156 void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
2157     if (fHWGeometryState.fIndexBuffer == buffer) {
2158         // deleting bound buffer does implied bind to 0
2159         fHWGeometryState.fIndexBuffer = NULL;
2160     }
2161 }
2162 
notifyRenderTargetDelete(GrRenderTarget * renderTarget)2163 void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
2164     GrAssert(NULL != renderTarget);
2165     GrDrawState* drawState = this->drawState();
2166     if (drawState->getRenderTarget() == renderTarget) {
2167         drawState->setRenderTarget(NULL);
2168     }
2169     if (fHWDrawState.getRenderTarget() == renderTarget) {
2170         fHWDrawState.setRenderTarget(NULL);
2171     }
2172 }
2173 
notifyTextureDelete(GrGLTexture * texture)2174 void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
2175     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
2176         GrDrawState* drawState = this->drawState();
2177         if (drawState->getTexture(s) == texture) {
2178             fCurrDrawState.setTexture(s, NULL);
2179         }
2180         if (fHWDrawState.getTexture(s) == texture) {
2181             // deleting bound texture does implied bind to 0
2182             fHWDrawState.setTexture(s, NULL);
2183        }
2184     }
2185 }
2186 
configToGLFormats(GrPixelConfig config,bool getSizedInternalFormat,GrGLenum * internalFormat,GrGLenum * externalFormat,GrGLenum * externalType)2187 bool GrGpuGL::configToGLFormats(GrPixelConfig config,
2188                                 bool getSizedInternalFormat,
2189                                 GrGLenum* internalFormat,
2190                                 GrGLenum* externalFormat,
2191                                 GrGLenum* externalType) {
2192     GrGLenum dontCare;
2193     if (NULL == internalFormat) {
2194         internalFormat = &dontCare;
2195     }
2196     if (NULL == externalFormat) {
2197         externalFormat = &dontCare;
2198     }
2199     if (NULL == externalType) {
2200         externalType = &dontCare;
2201     }
2202 
2203     switch (config) {
2204         case kRGBA_8888_PM_GrPixelConfig:
2205         case kRGBA_8888_UPM_GrPixelConfig:
2206             *internalFormat = GR_GL_RGBA;
2207             *externalFormat = GR_GL_RGBA;
2208             if (getSizedInternalFormat) {
2209                 *internalFormat = GR_GL_RGBA8;
2210             } else {
2211                 *internalFormat = GR_GL_RGBA;
2212             }
2213             *externalType = GR_GL_UNSIGNED_BYTE;
2214             break;
2215         case kBGRA_8888_PM_GrPixelConfig:
2216         case kBGRA_8888_UPM_GrPixelConfig:
2217             if (!this->glCaps().bgraFormatSupport()) {
2218                 return false;
2219             }
2220             if (this->glCaps().bgraIsInternalFormat()) {
2221                 if (getSizedInternalFormat) {
2222                     *internalFormat = GR_GL_BGRA8;
2223                 } else {
2224                     *internalFormat = GR_GL_BGRA;
2225                 }
2226             } else {
2227                 if (getSizedInternalFormat) {
2228                     *internalFormat = GR_GL_RGBA8;
2229                 } else {
2230                     *internalFormat = GR_GL_RGBA;
2231                 }
2232             }
2233             *externalFormat = GR_GL_BGRA;
2234             *externalType = GR_GL_UNSIGNED_BYTE;
2235             break;
2236         case kRGB_565_GrPixelConfig:
2237             *internalFormat = GR_GL_RGB;
2238             *externalFormat = GR_GL_RGB;
2239             if (getSizedInternalFormat) {
2240                 if (this->glBinding() == kDesktop_GrGLBinding) {
2241                     return false;
2242                 } else {
2243                     *internalFormat = GR_GL_RGB565;
2244                 }
2245             } else {
2246                 *internalFormat = GR_GL_RGB;
2247             }
2248             *externalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2249             break;
2250         case kRGBA_4444_GrPixelConfig:
2251             *internalFormat = GR_GL_RGBA;
2252             *externalFormat = GR_GL_RGBA;
2253             if (getSizedInternalFormat) {
2254                 *internalFormat = GR_GL_RGBA4;
2255             } else {
2256                 *internalFormat = GR_GL_RGBA;
2257             }
2258             *externalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
2259             break;
2260         case kIndex_8_GrPixelConfig:
2261             if (this->getCaps().f8BitPaletteSupport) {
2262                 *internalFormat = GR_GL_PALETTE8_RGBA8;
2263                 // glCompressedTexImage doesn't take external params
2264                 *externalFormat = GR_GL_PALETTE8_RGBA8;
2265                 // no sized/unsized internal format distinction here
2266                 *internalFormat = GR_GL_PALETTE8_RGBA8;
2267                 // unused with CompressedTexImage
2268                 *externalType = GR_GL_UNSIGNED_BYTE;
2269             } else {
2270                 return false;
2271             }
2272             break;
2273         case kAlpha_8_GrPixelConfig:
2274             *internalFormat = GR_GL_ALPHA;
2275             *externalFormat = GR_GL_ALPHA;
2276             if (getSizedInternalFormat) {
2277                 *internalFormat = GR_GL_ALPHA8;
2278             } else {
2279                 *internalFormat = GR_GL_ALPHA;
2280             }
2281             *externalType = GR_GL_UNSIGNED_BYTE;
2282             break;
2283         default:
2284             return false;
2285     }
2286     return true;
2287 }
2288 
setTextureUnit(int unit)2289 void GrGpuGL::setTextureUnit(int unit) {
2290     GrAssert(unit >= 0 && unit < GrDrawState::kNumStages);
2291     if (fActiveTextureUnitIdx != unit) {
2292         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
2293         fActiveTextureUnitIdx = unit;
2294     }
2295 }
2296 
setSpareTextureUnit()2297 void GrGpuGL::setSpareTextureUnit() {
2298     if (fActiveTextureUnitIdx != (GR_GL_TEXTURE0 + SPARE_TEX_UNIT)) {
2299         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT));
2300         fActiveTextureUnitIdx = SPARE_TEX_UNIT;
2301     }
2302 }
2303 
resetDirtyFlags()2304 void GrGpuGL::resetDirtyFlags() {
2305     Gr_bzero(&fDirtyFlags, sizeof(fDirtyFlags));
2306 }
2307 
setBuffers(bool indexed,int * extraVertexOffset,int * extraIndexOffset)2308 void GrGpuGL::setBuffers(bool indexed,
2309                          int* extraVertexOffset,
2310                          int* extraIndexOffset) {
2311 
2312     GrAssert(NULL != extraVertexOffset);
2313 
2314     const GeometryPoolState& geoPoolState = this->getGeomPoolState();
2315 
2316     GrGLVertexBuffer* vbuf;
2317     switch (this->getGeomSrc().fVertexSrc) {
2318     case kBuffer_GeometrySrcType:
2319         *extraVertexOffset = 0;
2320         vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
2321         break;
2322     case kArray_GeometrySrcType:
2323     case kReserved_GeometrySrcType:
2324         this->finalizeReservedVertices();
2325         *extraVertexOffset = geoPoolState.fPoolStartVertex;
2326         vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
2327         break;
2328     default:
2329         vbuf = NULL; // suppress warning
2330         GrCrash("Unknown geometry src type!");
2331     }
2332 
2333     GrAssert(NULL != vbuf);
2334     GrAssert(!vbuf->isLocked());
2335     if (fHWGeometryState.fVertexBuffer != vbuf) {
2336         GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, vbuf->bufferID()));
2337         fHWGeometryState.fArrayPtrsDirty = true;
2338         fHWGeometryState.fVertexBuffer = vbuf;
2339     }
2340 
2341     if (indexed) {
2342         GrAssert(NULL != extraIndexOffset);
2343 
2344         GrGLIndexBuffer* ibuf;
2345         switch (this->getGeomSrc().fIndexSrc) {
2346         case kBuffer_GeometrySrcType:
2347             *extraIndexOffset = 0;
2348             ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
2349             break;
2350         case kArray_GeometrySrcType:
2351         case kReserved_GeometrySrcType:
2352             this->finalizeReservedIndices();
2353             *extraIndexOffset = geoPoolState.fPoolStartIndex;
2354             ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;
2355             break;
2356         default:
2357             ibuf = NULL; // suppress warning
2358             GrCrash("Unknown geometry src type!");
2359         }
2360 
2361         GrAssert(NULL != ibuf);
2362         GrAssert(!ibuf->isLocked());
2363         if (fHWGeometryState.fIndexBuffer != ibuf) {
2364             GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibuf->bufferID()));
2365             fHWGeometryState.fIndexBuffer = ibuf;
2366         }
2367     }
2368 }
2369 
getMaxEdges() const2370 int GrGpuGL::getMaxEdges() const {
2371     // FIXME:  This is a pessimistic estimate based on how many other things
2372     // want to add uniforms.  This should be centralized somewhere.
2373     return GR_CT_MIN(this->glCaps().maxFragmentUniformVectors() - 8,
2374                      GrDrawState::kMaxEdges);
2375 }
2376 
2377