• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2010, Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 
33 #if ENABLE(ACCELERATED_2D_CANVAS)
34 
35 #include "SharedGraphicsContext3D.h"
36 
37 #include "AffineTransform.h"
38 #include "BicubicShader.h"
39 #include "Color.h"
40 #include "ConvolutionShader.h"
41 #include "DrawingBuffer.h"
42 #include "Extensions3D.h"
43 #include "FloatRect.h"
44 #include "IntSize.h"
45 #include "LoopBlinnSolidFillShader.h"
46 #include "SolidFillShader.h"
47 #include "TexShader.h"
48 
49 #if ENABLE(SKIA_GPU)
50 #include "GrContext.h"
51 // Limit the number of textures we hold in the bitmap->texture cache.
52 static const int maxTextureCacheCount = 512;
53 // Limit the bytes allocated toward textures in the bitmap->texture cache.
54 static const size_t maxTextureCacheBytes = 50 * 1024 * 1024;
55 #endif
56 
57 #include <wtf/OwnArrayPtr.h>
58 #include <wtf/text/CString.h>
59 #include <wtf/text/WTFString.h>
60 
61 namespace WebCore {
62 
63 // static
create(HostWindow * hostWindow)64 PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow* hostWindow)
65 {
66     GraphicsContext3D::Attributes attr;
67     attr.depth = false;
68     attr.stencil = true;
69     attr.antialias = useLoopBlinnForPathRendering();
70     attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts.
71     RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow);
72     if (!context)
73         return 0;
74     OwnPtr<SolidFillShader> solidFillShader = SolidFillShader::create(context.get());
75     if (!solidFillShader)
76         return 0;
77     OwnPtr<TexShader> texShader = TexShader::create(context.get());
78     if (!texShader)
79         return 0;
80     OwnPtr<BicubicShader> bicubicShader = BicubicShader::create(context.get());
81     if (!bicubicShader)
82         return 0;
83     OwnArrayPtr<OwnPtr<ConvolutionShader> > convolutionShaders = adoptArrayPtr(new OwnPtr<ConvolutionShader>[cMaxKernelWidth]);
84     for (int i = 0; i < cMaxKernelWidth; ++i) {
85         convolutionShaders[i] = ConvolutionShader::create(context.get(), i + 1);
86         if (!convolutionShaders[i])
87             return 0;
88     }
89     return adoptRef(new SharedGraphicsContext3D(context.release(), solidFillShader.release(), texShader.release(), bicubicShader.release(), convolutionShaders.release()));
90 }
91 
SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> context,PassOwnPtr<SolidFillShader> solidFillShader,PassOwnPtr<TexShader> texShader,PassOwnPtr<BicubicShader> bicubicShader,PassOwnArrayPtr<OwnPtr<ConvolutionShader>> convolutionShaders)92 SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<SolidFillShader> solidFillShader, PassOwnPtr<TexShader> texShader, PassOwnPtr<BicubicShader> bicubicShader, PassOwnArrayPtr<OwnPtr<ConvolutionShader> > convolutionShaders)
93     : m_context(context)
94     , m_bgraSupported(false)
95     , m_quadVertices(0)
96     , m_solidFillShader(solidFillShader)
97     , m_texShader(texShader)
98     , m_bicubicShader(bicubicShader)
99     , m_convolutionShaders(convolutionShaders)
100     , m_oesStandardDerivativesSupported(false)
101 #if ENABLE(SKIA_GPU)
102     , m_grContext(0)
103 #endif
104 {
105     allContexts()->add(this);
106     Extensions3D* extensions = m_context->getExtensions();
107     m_bgraSupported = extensions->supports("GL_EXT_texture_format_BGRA8888") && extensions->supports("GL_EXT_read_format_bgra");
108     if (m_bgraSupported) {
109         extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");
110         extensions->ensureEnabled("GL_EXT_read_format_bgra");
111     }
112     m_oesStandardDerivativesSupported = extensions->supports("GL_OES_standard_derivatives");
113     if (m_oesStandardDerivativesSupported)
114         extensions->ensureEnabled("GL_OES_standard_derivatives");
115 }
116 
~SharedGraphicsContext3D()117 SharedGraphicsContext3D::~SharedGraphicsContext3D()
118 {
119     m_context->deleteBuffer(m_quadVertices);
120     allContexts()->remove(this);
121 #if ENABLE(SKIA_GPU)
122     GrSafeUnref(m_grContext);
123 #endif
124 }
125 
makeContextCurrent()126 void SharedGraphicsContext3D::makeContextCurrent()
127 {
128     m_context->makeContextCurrent();
129 }
130 
scissor(GC3Dint x,GC3Dint y,GC3Dsizei width,GC3Dsizei height)131 void SharedGraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
132 {
133     m_context->scissor(x, y, width, height);
134 }
135 
enable(GC3Denum capacity)136 void SharedGraphicsContext3D::enable(GC3Denum capacity)
137 {
138     m_context->enable(capacity);
139 }
140 
disable(GC3Denum capacity)141 void SharedGraphicsContext3D::disable(GC3Denum capacity)
142 {
143     m_context->disable(capacity);
144 }
145 
clearColor(const Color & color)146 void SharedGraphicsContext3D::clearColor(const Color& color)
147 {
148     float rgba[4];
149     color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
150     m_context->clearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
151 }
152 
clear(GC3Dbitfield mask)153 void SharedGraphicsContext3D::clear(GC3Dbitfield mask)
154 {
155     m_context->clear(mask);
156 }
157 
drawArrays(GC3Denum mode,GC3Dint first,GC3Dsizei count)158 void SharedGraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
159 {
160     m_context->drawArrays(mode, first, count);
161 }
162 
getError()163 GC3Denum SharedGraphicsContext3D::getError()
164 {
165     return m_context->getError();
166 }
167 
getIntegerv(GC3Denum pname,GC3Dint * value)168 void SharedGraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
169 {
170     m_context->getIntegerv(pname, value);
171 }
172 
flush()173 void SharedGraphicsContext3D::flush()
174 {
175     m_context->flush();
176 }
177 
createBuffer()178 Platform3DObject SharedGraphicsContext3D::createBuffer()
179 {
180     return m_context->createBuffer();
181 }
182 
createFramebuffer()183 Platform3DObject SharedGraphicsContext3D::createFramebuffer()
184 {
185     return m_context->createFramebuffer();
186 }
187 
createTexture()188 Platform3DObject SharedGraphicsContext3D::createTexture()
189 {
190     return m_context->createTexture();
191 }
192 
deleteFramebuffer(Platform3DObject framebuffer)193 void SharedGraphicsContext3D::deleteFramebuffer(Platform3DObject framebuffer)
194 {
195     m_context->deleteFramebuffer(framebuffer);
196 }
197 
deleteTexture(Platform3DObject texture)198 void SharedGraphicsContext3D::deleteTexture(Platform3DObject texture)
199 {
200     m_context->deleteTexture(texture);
201 }
202 
framebufferTexture2D(GC3Denum target,GC3Denum attachment,GC3Denum textarget,Platform3DObject texture,GC3Dint level)203 void SharedGraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level)
204 {
205     m_context->framebufferTexture2D(target, attachment, textarget, texture, level);
206 }
207 
texParameteri(GC3Denum target,GC3Denum pname,GC3Dint param)208 void SharedGraphicsContext3D::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
209 {
210     m_context->texParameteri(target, pname, param);
211 }
212 
texImage2D(GC3Denum target,GC3Dint level,GC3Denum internalformat,GC3Dsizei width,GC3Dsizei height,GC3Dint border,GC3Denum format,GC3Denum type,const void * pixels)213 bool SharedGraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
214 {
215     if (!pixels)
216         return m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border, format, type);
217     return m_context->texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
218 }
219 
texSubImage2D(GC3Denum target,GC3Dint level,GC3Dint xoffset,GC3Dint yoffset,GC3Dsizei width,GC3Dsizei height,GC3Denum format,GC3Denum type,const void * pixels)220 void SharedGraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
221 {
222     m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
223 }
224 
readPixels(GC3Dint x,GC3Dint y,GC3Dsizei width,GC3Dsizei height,GC3Denum format,GC3Denum type,void * data)225 void SharedGraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
226 {
227     m_context->readPixels(x, y, width, height, format, type, data);
228 }
229 
supportsBGRA()230 bool SharedGraphicsContext3D::supportsBGRA()
231 {
232     return m_bgraSupported;
233 }
234 
createTexture(NativeImagePtr ptr,Texture::Format format,int width,int height)235 Texture* SharedGraphicsContext3D::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height)
236 {
237     RefPtr<Texture> texture = m_textures.get(ptr);
238     if (texture)
239         return texture.get();
240 
241     texture = Texture::create(m_context.get(), format, width, height);
242     Texture* t = texture.get();
243     m_textures.set(ptr, texture);
244     return t;
245 }
246 
getTexture(NativeImagePtr ptr)247 Texture* SharedGraphicsContext3D::getTexture(NativeImagePtr ptr)
248 {
249     RefPtr<Texture> texture = m_textures.get(ptr);
250     return texture ? texture.get() : 0;
251 }
252 
removeTextureFor(NativeImagePtr ptr)253 void SharedGraphicsContext3D::removeTextureFor(NativeImagePtr ptr)
254 {
255     TextureHashMap::iterator it = m_textures.find(ptr);
256     if (it != m_textures.end())
257         m_textures.remove(it);
258 }
259 
260 // static
removeTexturesFor(NativeImagePtr ptr)261 void SharedGraphicsContext3D::removeTexturesFor(NativeImagePtr ptr)
262 {
263     for (HashSet<SharedGraphicsContext3D*>::iterator it = allContexts()->begin(); it != allContexts()->end(); ++it)
264         (*it)->removeTextureFor(ptr);
265 }
266 
267 // static
allContexts()268 HashSet<SharedGraphicsContext3D*>* SharedGraphicsContext3D::allContexts()
269 {
270     DEFINE_STATIC_LOCAL(HashSet<SharedGraphicsContext3D*>, allContextsSet, ());
271     return &allContextsSet;
272 }
273 
274 
createTexture(Texture::Format format,int width,int height)275 PassRefPtr<Texture> SharedGraphicsContext3D::createTexture(Texture::Format format, int width, int height)
276 {
277     return Texture::create(m_context.get(), format, width, height);
278 }
279 
applyCompositeOperator(CompositeOperator op)280 void SharedGraphicsContext3D::applyCompositeOperator(CompositeOperator op)
281 {
282     switch (op) {
283     case CompositeClear:
284         m_context->enable(GraphicsContext3D::BLEND);
285         m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ZERO);
286         break;
287     case CompositeCopy:
288         m_context->disable(GraphicsContext3D::BLEND);
289         break;
290     case CompositeSourceOver:
291         m_context->enable(GraphicsContext3D::BLEND);
292         m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
293         break;
294     case CompositeSourceIn:
295         m_context->enable(GraphicsContext3D::BLEND);
296         m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ZERO);
297         break;
298     case CompositeSourceOut:
299         m_context->enable(GraphicsContext3D::BLEND);
300         m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ZERO);
301         break;
302     case CompositeSourceAtop:
303         m_context->enable(GraphicsContext3D::BLEND);
304         m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
305         break;
306     case CompositeDestinationOver:
307         m_context->enable(GraphicsContext3D::BLEND);
308         m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE);
309         break;
310     case CompositeDestinationIn:
311         m_context->enable(GraphicsContext3D::BLEND);
312         m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::SRC_ALPHA);
313         break;
314     case CompositeDestinationOut:
315         m_context->enable(GraphicsContext3D::BLEND);
316         m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
317         break;
318     case CompositeDestinationAtop:
319         m_context->enable(GraphicsContext3D::BLEND);
320         m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::SRC_ALPHA);
321         break;
322     case CompositeXOR:
323         m_context->enable(GraphicsContext3D::BLEND);
324         m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
325         break;
326     case CompositePlusDarker:
327     case CompositeHighlight:
328         // unsupported
329         m_context->disable(GraphicsContext3D::BLEND);
330         break;
331     case CompositePlusLighter:
332         m_context->enable(GraphicsContext3D::BLEND);
333         m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE);
334         break;
335     }
336 }
337 
enableStencil(bool enable)338 void SharedGraphicsContext3D::enableStencil(bool enable)
339 {
340     if (enable)
341         m_context->enable(GraphicsContext3D::STENCIL_TEST);
342     else
343         m_context->disable(GraphicsContext3D::STENCIL_TEST);
344 }
345 
useQuadVertices()346 void SharedGraphicsContext3D::useQuadVertices()
347 {
348     if (!m_quadVertices) {
349         float vertices[] = { 0.0f, 0.0f,
350                              1.0f, 0.0f,
351                              0.0f, 1.0f,
352                              1.0f, 1.0f };
353         m_quadVertices = m_context->createBuffer();
354         m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
355         m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
356     } else {
357         m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
358     }
359 }
360 
setActiveTexture(GC3Denum textureUnit)361 void SharedGraphicsContext3D::setActiveTexture(GC3Denum textureUnit)
362 {
363     m_context->activeTexture(textureUnit);
364 }
365 
bindBuffer(GC3Denum target,Platform3DObject buffer)366 void SharedGraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
367 {
368     m_context->bindBuffer(target, buffer);
369 }
370 
bindTexture(GC3Denum target,Platform3DObject texture)371 void SharedGraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
372 {
373     m_context->bindTexture(target, texture);
374 }
375 
bufferData(GC3Denum target,GC3Dsizeiptr size,GC3Denum usage)376 void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
377 {
378     m_context->bufferData(target, size, usage);
379 }
380 
bufferData(GC3Denum target,GC3Dsizeiptr size,const void * data,GC3Denum usage)381 void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
382 {
383     m_context->bufferData(target, size, data, usage);
384 }
385 
bufferSubData(GC3Denum target,GC3Dintptr offset,GC3Dsizeiptr size,const void * data)386 void SharedGraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
387 {
388     m_context->bufferSubData(target, offset, size, data);
389 }
390 
useFillSolidProgram(const AffineTransform & transform,const Color & color)391 void SharedGraphicsContext3D::useFillSolidProgram(const AffineTransform& transform, const Color& color)
392 {
393     m_solidFillShader->use(transform, color);
394 }
395 
useTextureProgram(const AffineTransform & transform,const AffineTransform & texTransform,float alpha)396 void SharedGraphicsContext3D::useTextureProgram(const AffineTransform& transform, const AffineTransform& texTransform, float alpha)
397 {
398     m_texShader->use(transform, texTransform, 0, alpha);
399 }
400 
useBicubicProgram(const AffineTransform & transform,const AffineTransform & texTransform,const float coefficients[16],const float imageIncrement[2],float alpha)401 void SharedGraphicsContext3D::useBicubicProgram(const AffineTransform& transform, const AffineTransform& texTransform, const float coefficients[16], const float imageIncrement[2], float alpha)
402 {
403     m_bicubicShader->use(transform, texTransform, coefficients, imageIncrement, alpha);
404 }
405 
useConvolutionProgram(const AffineTransform & transform,const AffineTransform & texTransform,const float * kernel,int kernelWidth,float imageIncrement[2])406 void SharedGraphicsContext3D::useConvolutionProgram(const AffineTransform& transform, const AffineTransform& texTransform, const float* kernel, int kernelWidth, float imageIncrement[2])
407 {
408     ASSERT(kernelWidth >= 1 && kernelWidth <= cMaxKernelWidth);
409     m_convolutionShaders[kernelWidth - 1]->use(transform, texTransform, kernel, kernelWidth, imageIncrement);
410 }
411 
bindFramebuffer(Platform3DObject framebuffer)412 void SharedGraphicsContext3D::bindFramebuffer(Platform3DObject framebuffer)
413 {
414     m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer);
415 }
416 
setViewport(const IntSize & size)417 void SharedGraphicsContext3D::setViewport(const IntSize& size)
418 {
419     m_context->viewport(0, 0, size.width(), size.height());
420 }
421 
paintsIntoCanvasBuffer() const422 bool SharedGraphicsContext3D::paintsIntoCanvasBuffer() const
423 {
424     return m_context->paintsIntoCanvasBuffer();
425 }
426 
useLoopBlinnForPathRendering()427 bool SharedGraphicsContext3D::useLoopBlinnForPathRendering()
428 {
429     return false;
430 }
431 
useLoopBlinnInteriorProgram(unsigned vertexOffset,const AffineTransform & transform,const Color & color)432 void SharedGraphicsContext3D::useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform& transform, const Color& color)
433 {
434     if (!m_loopBlinnInteriorShader) {
435         m_loopBlinnInteriorShader = LoopBlinnSolidFillShader::create(m_context.get(),
436                                                                      LoopBlinnShader::Interior,
437                                                                      Shader::NotAntialiased);
438     }
439     ASSERT(m_loopBlinnInteriorShader);
440     m_loopBlinnInteriorShader->use(vertexOffset, 0, transform, color);
441 }
442 
useLoopBlinnExteriorProgram(unsigned vertexOffset,unsigned klmOffset,const AffineTransform & transform,const Color & color)443 void SharedGraphicsContext3D::useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform& transform, const Color& color)
444 {
445     if (!m_loopBlinnExteriorShader) {
446         m_loopBlinnExteriorShader = LoopBlinnSolidFillShader::create(m_context.get(),
447                                                                      LoopBlinnShader::Exterior,
448                                                                      m_oesStandardDerivativesSupported ? Shader::Antialiased : Shader::NotAntialiased);
449     }
450     ASSERT(m_loopBlinnExteriorShader);
451     m_loopBlinnExteriorShader->use(vertexOffset, klmOffset, transform, color);
452 }
453 
getOffscreenBuffer(unsigned index,const IntSize & size)454 DrawingBuffer* SharedGraphicsContext3D::getOffscreenBuffer(unsigned index, const IntSize& size)
455 {
456     if (index >= m_offscreenBuffers.size())
457         m_offscreenBuffers.resize(index + 1);
458 
459     if (!m_offscreenBuffers[index])
460         m_offscreenBuffers[index] = m_context->createDrawingBuffer(size);
461 
462     if (size.width() != m_offscreenBuffers[index]->size().width()
463         || size.height() != m_offscreenBuffers[index]->size().height())
464         m_offscreenBuffers[index]->reset(size);
465     return m_offscreenBuffers[index].get();
466 }
467 
468 #if ENABLE(SKIA_GPU)
grContext()469 GrContext* SharedGraphicsContext3D::grContext()
470 {
471     if (!m_grContext) {
472         m_grContext = GrContext::CreateGLShaderContext();
473         m_grContext->setTextureCacheLimits(maxTextureCacheCount, maxTextureCacheBytes);
474     }
475     return m_grContext;
476 }
477 #endif
478 
479 } // namespace WebCore
480 
481 #endif
482