Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: webkit/gpu/webgraphicscontext3d_in_process_impl.cc

Issue 16046003: Move webkit/gpu into webkit/common/gpu (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix includes in content/common/gpu/client/gl_helper_* Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
6
7 #include <string.h>
8
9 #include <algorithm>
10 #include <string>
11 #include <vector>
12
13 #include "base/lazy_instance.h"
14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/strings/string_split.h"
17 #include "base/synchronization/lock.h"
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
19 #include "ui/gl/gl_bindings.h"
20 #include "ui/gl/gl_bindings_skia_in_process.h"
21 #include "ui/gl/gl_context.h"
22 #include "ui/gl/gl_implementation.h"
23 #include "ui/gl/gl_surface.h"
24
25 namespace webkit {
26 namespace gpu {
27
28 enum {
29 MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB,
30 MAX_VARYING_VECTORS = 0x8DFC,
31 MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD
32 };
33
34 struct WebGraphicsContext3DInProcessImpl::ShaderSourceEntry {
35 explicit ShaderSourceEntry(WGC3Denum shader_type)
36 : type(shader_type),
37 is_valid(false) {
38 }
39
40 WGC3Denum type;
41 scoped_ptr<char[]> source;
42 scoped_ptr<char[]> log;
43 scoped_ptr<char[]> translated_source;
44 bool is_valid;
45 };
46
47 WebGraphicsContext3DInProcessImpl::WebGraphicsContext3DInProcessImpl(
48 gfx::GLSurface* surface,
49 gfx::GLContext* context,
50 bool render_directly_to_web_view)
51 : initialized_(false),
52 render_directly_to_web_view_(render_directly_to_web_view),
53 is_gles2_(false),
54 have_ext_framebuffer_object_(false),
55 have_ext_framebuffer_multisample_(false),
56 have_angle_framebuffer_multisample_(false),
57 have_ext_oes_standard_derivatives_(false),
58 have_ext_oes_egl_image_external_(false),
59 texture_(0),
60 fbo_(0),
61 depth_stencil_buffer_(0),
62 cached_width_(0),
63 cached_height_(0),
64 multisample_fbo_(0),
65 multisample_depth_stencil_buffer_(0),
66 multisample_color_buffer_(0),
67 bound_fbo_(0),
68 bound_texture_(0),
69 scanline_(0),
70 gl_context_(context),
71 gl_surface_(surface),
72 fragment_compiler_(0),
73 vertex_compiler_(0) {
74 }
75
76 // All instances in a process that share resources are in the same share group.
77 static base::LazyInstance<
78 std::set<WebGraphicsContext3DInProcessImpl*> >
79 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;
80 static base::LazyInstance<base::Lock>::Leaky
81 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER;
82
83 WebGraphicsContext3DInProcessImpl::~WebGraphicsContext3DInProcessImpl() {
84 base::AutoLock a(g_all_shared_contexts_lock.Get());
85 g_all_shared_contexts.Pointer()->erase(this);
86
87 if (!initialized_)
88 return;
89
90 makeContextCurrent();
91
92 if (attributes_.antialias) {
93 glDeleteRenderbuffersEXT(1, &multisample_color_buffer_);
94 if (attributes_.depth || attributes_.stencil)
95 glDeleteRenderbuffersEXT(1, &multisample_depth_stencil_buffer_);
96 glDeleteFramebuffersEXT(1, &multisample_fbo_);
97 } else {
98 if (attributes_.depth || attributes_.stencil)
99 glDeleteRenderbuffersEXT(1, &depth_stencil_buffer_);
100 }
101 glDeleteTextures(1, &texture_);
102 if (scanline_)
103 delete[] scanline_;
104 glDeleteFramebuffersEXT(1, &fbo_);
105
106 gl_context_->ReleaseCurrent(gl_surface_.get());
107 gl_context_->Destroy();
108 gl_surface_->Destroy();
109
110 for (ShaderSourceMap::iterator ii = shader_source_map_.begin();
111 ii != shader_source_map_.end(); ++ii) {
112 if (ii->second)
113 delete ii->second;
114 }
115 AngleDestroyCompilers();
116 }
117
118 WebGraphicsContext3DInProcessImpl*
119 WebGraphicsContext3DInProcessImpl::CreateForWindow(
120 WebGraphicsContext3D::Attributes attributes,
121 gfx::AcceleratedWidget window,
122 gfx::GLShareGroup* share_group) {
123 if (!gfx::GLSurface::InitializeOneOff())
124 return NULL;
125
126 scoped_refptr<gfx::GLSurface> gl_surface =
127 gfx::GLSurface::CreateViewGLSurface(false, window);
128 if (!gl_surface)
129 return NULL;
130
131 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
132
133 scoped_refptr<gfx::GLContext> gl_context = gfx::GLContext::CreateGLContext(
134 share_group,
135 gl_surface.get(),
136 gpu_preference);
137 if (!gl_context)
138 return NULL;
139 scoped_ptr<WebGraphicsContext3DInProcessImpl> context(
140 new WebGraphicsContext3DInProcessImpl(
141 gl_surface.get(), gl_context.get(), true));
142 if (!context->Initialize(attributes))
143 return NULL;
144 return context.release();
145 }
146
147 bool WebGraphicsContext3DInProcessImpl::Initialize(
148 WebGraphicsContext3D::Attributes attributes) {
149 is_gles2_ = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
150
151
152 attributes_ = attributes;
153
154 // FIXME: for the moment we disable multisampling for the compositor.
155 // It actually works in this implementation, but there are a few
156 // considerations. First, we likely want to reduce the fuzziness in
157 // these tests as much as possible because we want to run pixel tests.
158 // Second, Mesa's multisampling doesn't seem to antialias straight
159 // edges in some CSS 3D samples. Third, we don't have multisampling
160 // support for the compositor in the normal case at the time of this
161 // writing.
162 if (render_directly_to_web_view_)
163 attributes_.antialias = false;
164
165 if (!gl_context_->MakeCurrent(gl_surface_)) {
166 gl_context_ = NULL;
167 return false;
168 }
169
170 const char* extensions =
171 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
172 DCHECK(extensions);
173 have_ext_framebuffer_object_ =
174 strstr(extensions, "GL_EXT_framebuffer_object") != NULL;
175 have_ext_framebuffer_multisample_ =
176 strstr(extensions, "GL_EXT_framebuffer_multisample") != NULL;
177 #if !defined(OS_ANDROID)
178 // Some Android Qualcomm drivers falsely report this ANGLE extension string.
179 // See http://crbug.com/165736
180 have_angle_framebuffer_multisample_ =
181 strstr(extensions, "GL_ANGLE_framebuffer_multisample") != NULL;
182 #endif
183 have_ext_oes_standard_derivatives_ =
184 strstr(extensions, "GL_OES_standard_derivatives") != NULL;
185 have_ext_oes_egl_image_external_ =
186 strstr(extensions, "GL_OES_EGL_image_external") != NULL;
187
188 ValidateAttributes();
189
190 if (!is_gles2_) {
191 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
192 glEnable(GL_POINT_SPRITE);
193 }
194
195 if (!AngleCreateCompilers()) {
196 AngleDestroyCompilers();
197 return false;
198 }
199
200 initialized_ = true;
201 gl_context_->ReleaseCurrent(gl_surface_.get());
202
203 if (attributes_.shareResources)
204 g_all_shared_contexts.Pointer()->insert(this);
205
206 return true;
207 }
208
209 void WebGraphicsContext3DInProcessImpl::ValidateAttributes() {
210 const char* extensions =
211 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
212
213 if (attributes_.stencil) {
214 if (strstr(extensions, "GL_OES_packed_depth_stencil") ||
215 strstr(extensions, "GL_EXT_packed_depth_stencil")) {
216 if (!attributes_.depth) {
217 attributes_.depth = true;
218 }
219 } else {
220 attributes_.stencil = false;
221 }
222 }
223 if (attributes_.antialias) {
224 bool isValidVendor = true;
225 #if defined(OS_MACOSX)
226 // Currently in Mac we only turn on antialias if vendor is NVIDIA.
227 const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
228 if (!strstr(vendor, "NVIDIA"))
229 isValidVendor = false;
230 #endif
231 if (!(isValidVendor &&
232 (have_ext_framebuffer_multisample_ ||
233 (have_angle_framebuffer_multisample_ &&
234 strstr(extensions, "GL_OES_rgb8_rgba8")))))
235 attributes_.antialias = false;
236
237 // Don't antialias when using Mesa to ensure more reliable testing and
238 // because it doesn't appear to multisample straight lines correctly.
239 const char* renderer =
240 reinterpret_cast<const char*>(glGetString(GL_RENDERER));
241 if (!strncmp(renderer, "Mesa", 4)) {
242 attributes_.antialias = false;
243 }
244 }
245 }
246
247 void WebGraphicsContext3DInProcessImpl::ResolveMultisampledFramebuffer(
248 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) {
249 if (attributes_.antialias) {
250 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, multisample_fbo_);
251 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo_);
252 if (have_ext_framebuffer_multisample_) {
253 glBlitFramebufferEXT(x, y,
254 x + width, y + height,
255 x, y,
256 x + width, y + height,
257 GL_COLOR_BUFFER_BIT, GL_NEAREST);
258 } else {
259 DCHECK(have_angle_framebuffer_multisample_);
260 glBlitFramebufferANGLE(x, y,
261 x + width, y + height,
262 x, y,
263 x + width, y + height,
264 GL_COLOR_BUFFER_BIT, GL_NEAREST);
265 }
266 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
267 }
268 }
269
270 bool WebGraphicsContext3DInProcessImpl::makeContextCurrent() {
271 return gl_context_->MakeCurrent(gl_surface_.get());
272 }
273
274 int WebGraphicsContext3DInProcessImpl::width() {
275 return cached_width_;
276 }
277
278 int WebGraphicsContext3DInProcessImpl::height() {
279 return cached_height_;
280 }
281
282 bool WebGraphicsContext3DInProcessImpl::isGLES2Compliant() {
283 return is_gles2_;
284 }
285
286 bool WebGraphicsContext3DInProcessImpl::setParentContext(
287 WebGraphicsContext3D* parent_context) {
288 return false;
289 }
290
291 WebGLId WebGraphicsContext3DInProcessImpl::getPlatformTextureId() {
292 return texture_;
293 }
294
295 void WebGraphicsContext3DInProcessImpl::prepareTexture() {
296 if (!gl_surface_->IsOffscreen()) {
297 gl_surface_->SwapBuffers();
298 } else if (!render_directly_to_web_view_) {
299 // We need to prepare our rendering results for the compositor.
300 makeContextCurrent();
301 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_);
302 }
303 }
304
305 void WebGraphicsContext3DInProcessImpl::postSubBufferCHROMIUM(
306 int x, int y, int width, int height) {
307 DCHECK(gl_surface_->HasExtension("GL_CHROMIUM_post_sub_buffer"));
308 gl_surface_->PostSubBuffer(x, y, width, height);
309 }
310
311 namespace {
312
313 int CreateTextureObject(GLenum target) {
314 GLuint texture = 0;
315 glGenTextures(1, &texture);
316 glBindTexture(target, texture);
317 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
318 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
319 return texture;
320 }
321
322 } // anonymous namespace
323
324 void WebGraphicsContext3DInProcessImpl::reshape(int width, int height) {
325 cached_width_ = width;
326 cached_height_ = height;
327 makeContextCurrent();
328
329 bool must_restore_fbo = false;
330 if (gl_surface_->IsOffscreen())
331 must_restore_fbo = AllocateOffscreenFrameBuffer(width, height);
332
333 gl_surface_->Resize(gfx::Size(width, height));
334 ClearRenderTarget();
335
336 if (must_restore_fbo)
337 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
338
339 if (scanline_) {
340 delete[] scanline_;
341 scanline_ = 0;
342 }
343 scanline_ = new unsigned char[width * 4];
344 }
345
346 void WebGraphicsContext3DInProcessImpl::reshapeWithScaleFactor(
347 int width, int height, float scaleFactor) {
348 reshape(width, height);
349 }
350
351 bool WebGraphicsContext3DInProcessImpl::AllocateOffscreenFrameBuffer(
352 int width, int height) {
353 GLenum target = GL_TEXTURE_2D;
354
355 if (!texture_) {
356 // Generate the texture object
357 texture_ = CreateTextureObject(target);
358 // Generate the framebuffer object
359 glGenFramebuffersEXT(1, &fbo_);
360 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
361 bound_fbo_ = fbo_;
362 if (attributes_.depth || attributes_.stencil)
363 glGenRenderbuffersEXT(1, &depth_stencil_buffer_);
364 // Generate the multisample framebuffer object
365 if (attributes_.antialias) {
366 glGenFramebuffersEXT(1, &multisample_fbo_);
367 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_);
368 bound_fbo_ = multisample_fbo_;
369 glGenRenderbuffersEXT(1, &multisample_color_buffer_);
370 if (attributes_.depth || attributes_.stencil)
371 glGenRenderbuffersEXT(1, &multisample_depth_stencil_buffer_);
372 }
373 }
374
375 GLint internal_multisampled_color_format = 0;
376 GLint internal_color_format = 0;
377 GLint color_format = 0;
378 GLint internal_depth_stencil_format = 0;
379 if (attributes_.alpha) {
380 // GL_RGBA8_OES == GL_RGBA8
381 internal_multisampled_color_format = GL_RGBA8;
382 internal_color_format = is_gles2_ ? GL_RGBA : GL_RGBA8;
383 color_format = GL_RGBA;
384 } else {
385 // GL_RGB8_OES == GL_RGB8
386 internal_multisampled_color_format = GL_RGB8;
387 internal_color_format = is_gles2_ ? GL_RGB : GL_RGB8;
388 color_format = GL_RGB;
389 }
390 if (attributes_.stencil || attributes_.depth) {
391 // We don't allow the logic where stencil is required and depth is not.
392 // See GraphicsContext3DInternal constructor.
393 if (attributes_.stencil && attributes_.depth) {
394 internal_depth_stencil_format = GL_DEPTH24_STENCIL8_EXT;
395 } else {
396 if (is_gles2_)
397 internal_depth_stencil_format = GL_DEPTH_COMPONENT16;
398 else
399 internal_depth_stencil_format = GL_DEPTH_COMPONENT;
400 }
401 }
402
403 bool must_restore_fbo = false;
404
405 // Resize multisampling FBO
406 if (attributes_.antialias) {
407 GLint max_sample_count;
408 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
409 GLint sample_count = std::min(8, max_sample_count);
410 if (bound_fbo_ != multisample_fbo_) {
411 must_restore_fbo = true;
412 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_);
413 }
414 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, multisample_color_buffer_);
415 if (have_ext_framebuffer_multisample_) {
416 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
417 sample_count,
418 internal_multisampled_color_format,
419 width,
420 height);
421 } else {
422 DCHECK(have_angle_framebuffer_multisample_);
423 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT,
424 sample_count,
425 internal_multisampled_color_format,
426 width,
427 height);
428 }
429 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
430 GL_COLOR_ATTACHMENT0_EXT,
431 GL_RENDERBUFFER_EXT,
432 multisample_color_buffer_);
433 if (attributes_.stencil || attributes_.depth) {
434 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
435 multisample_depth_stencil_buffer_);
436 if (have_ext_framebuffer_multisample_) {
437 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
438 sample_count,
439 internal_depth_stencil_format,
440 width,
441 height);
442 } else {
443 DCHECK(have_angle_framebuffer_multisample_);
444 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT,
445 sample_count,
446 internal_depth_stencil_format,
447 width,
448 height);
449 }
450 if (attributes_.stencil)
451 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
452 GL_STENCIL_ATTACHMENT_EXT,
453 GL_RENDERBUFFER_EXT,
454 multisample_depth_stencil_buffer_);
455 if (attributes_.depth)
456 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
457 GL_DEPTH_ATTACHMENT_EXT,
458 GL_RENDERBUFFER_EXT,
459 multisample_depth_stencil_buffer_);
460 }
461 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
462 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
463 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
464 LOG(ERROR) << "Multisampling framebuffer was incomplete";
465
466 // FIXME: cleanup.
467 NOTIMPLEMENTED();
468 }
469 }
470
471 // Resize regular FBO
472 if (bound_fbo_ != fbo_) {
473 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
474 must_restore_fbo = true;
475 }
476 glBindTexture(target, texture_);
477 glTexImage2D(target, 0, internal_color_format,
478 width, height,
479 0, color_format, GL_UNSIGNED_BYTE, 0);
480 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
481 GL_COLOR_ATTACHMENT0_EXT,
482 target,
483 texture_,
484 0);
485 glBindTexture(target, 0);
486 if (!attributes_.antialias && (attributes_.stencil || attributes_.depth)) {
487 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer_);
488 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
489 internal_depth_stencil_format,
490 width, height);
491 if (attributes_.stencil)
492 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
493 GL_STENCIL_ATTACHMENT_EXT,
494 GL_RENDERBUFFER_EXT,
495 depth_stencil_buffer_);
496 if (attributes_.depth)
497 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
498 GL_DEPTH_ATTACHMENT_EXT,
499 GL_RENDERBUFFER_EXT,
500 depth_stencil_buffer_);
501 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
502 }
503 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
504 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
505 LOG(ERROR) << "Framebuffer was incomplete";
506
507 // FIXME: cleanup.
508 NOTIMPLEMENTED();
509 }
510
511 if (attributes_.antialias) {
512 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_);
513 if (bound_fbo_ == multisample_fbo_)
514 must_restore_fbo = false;
515 }
516 return must_restore_fbo;
517 }
518
519 void WebGraphicsContext3DInProcessImpl::ClearRenderTarget() {
520 // Initialize renderbuffers to 0.
521 GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0;
522 GLint clearStencil = 0;
523 GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
524 GLboolean depthMask = GL_TRUE;
525 GLuint stencilMask = 0xffffffff;
526 GLboolean isScissorEnabled = GL_FALSE;
527 GLboolean isDitherEnabled = GL_FALSE;
528 GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
529 glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
530 glClearColor(0, 0, 0, 0);
531 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
532 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
533 if (attributes_.depth) {
534 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
535 glClearDepth(1);
536 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
537 glDepthMask(GL_TRUE);
538 clearMask |= GL_DEPTH_BUFFER_BIT;
539 }
540 if (attributes_.stencil) {
541 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil);
542 glClearStencil(0);
543 glGetIntegerv(GL_STENCIL_WRITEMASK,
544 reinterpret_cast<GLint*>(&stencilMask));
545 glStencilMaskSeparate(GL_FRONT, 0xffffffff);
546 clearMask |= GL_STENCIL_BUFFER_BIT;
547 }
548 isScissorEnabled = glIsEnabled(GL_SCISSOR_TEST);
549 glDisable(GL_SCISSOR_TEST);
550 isDitherEnabled = glIsEnabled(GL_DITHER);
551 glDisable(GL_DITHER);
552
553 glClear(clearMask);
554
555 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
556 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
557 if (attributes_.depth) {
558 glClearDepth(clearDepth);
559 glDepthMask(depthMask);
560 }
561 if (attributes_.stencil) {
562 glClearStencil(clearStencil);
563 glStencilMaskSeparate(GL_FRONT, stencilMask);
564 }
565 if (isScissorEnabled)
566 glEnable(GL_SCISSOR_TEST);
567 else
568 glDisable(GL_SCISSOR_TEST);
569 if (isDitherEnabled)
570 glEnable(GL_DITHER);
571 else
572 glDisable(GL_DITHER);
573 }
574
575 void WebGraphicsContext3DInProcessImpl::FlipVertically(
576 unsigned char* framebuffer, unsigned int width, unsigned int height) {
577 unsigned char* scanline = scanline_;
578 if (!scanline)
579 return;
580 unsigned int row_bytes = width * 4;
581 unsigned int count = height / 2;
582 for (unsigned int i = 0; i < count; i++) {
583 unsigned char* row_a = framebuffer + i * row_bytes;
584 unsigned char* row_b = framebuffer + (height - i - 1) * row_bytes;
585 // FIXME: this is where the multiplication of the alpha
586 // channel into the color buffer will need to occur if the
587 // user specifies the "premultiplyAlpha" flag in the context
588 // creation attributes.
589 memcpy(scanline, row_b, row_bytes);
590 memcpy(row_b, row_a, row_bytes);
591 memcpy(row_a, scanline, row_bytes);
592 }
593 }
594
595 bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
596 unsigned char* pixels, size_t bufferSize, WebGLId framebuffer,
597 int width, int height) {
598 if (bufferSize != static_cast<size_t>(4 * width * height))
599 return false;
600
601 makeContextCurrent();
602
603 // Earlier versions of this code used the GPU to flip the
604 // framebuffer vertically before reading it back for compositing
605 // via software. This code was quite complicated, used a lot of
606 // GPU memory, and didn't provide an obvious speedup. Since this
607 // vertical flip is only a temporary solution anyway until Chrome
608 // is fully GPU composited, it wasn't worth the complexity.
609
610 // In this implementation fbo_, not 0, is the drawing buffer, so
611 // special-case that.
612 if (framebuffer == 0)
613 framebuffer = fbo_;
614
615 if (framebuffer == fbo_)
616 ResolveMultisampledFramebuffer(0, 0, width, height);
617 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
618
619 GLint pack_alignment = 4;
620 bool must_restore_pack_alignment = false;
621 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
622 if (pack_alignment > 4) {
623 glPixelStorei(GL_PACK_ALIGNMENT, 4);
624 must_restore_pack_alignment = true;
625 }
626
627 if (is_gles2_) {
628 // FIXME: consider testing for presence of GL_OES_read_format
629 // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here
630 // directly.
631 glReadPixels(0, 0, width, height,
632 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
633 for (size_t i = 0; i < bufferSize; i += 4) {
634 std::swap(pixels[i], pixels[i + 2]);
635 }
636 } else {
637 glReadPixels(0, 0, width, height,
638 GL_BGRA, GL_UNSIGNED_BYTE, pixels);
639 }
640
641 if (must_restore_pack_alignment)
642 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
643
644 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
645
646 if (pixels)
647 FlipVertically(pixels, width, height);
648
649 return true;
650 }
651
652 bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
653 unsigned char* pixels, size_t bufferSize) {
654 return readBackFramebuffer(pixels, bufferSize, fbo_, width(), height());
655 }
656
657 void WebGraphicsContext3DInProcessImpl::synthesizeGLError(WGC3Denum error) {
658 if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) {
659 synthetic_errors_set_.insert(error);
660 synthetic_errors_list_.push_back(error);
661 }
662 }
663
664 void* WebGraphicsContext3DInProcessImpl::mapBufferSubDataCHROMIUM(
665 WGC3Denum target, WGC3Dintptr offset,
666 WGC3Dsizeiptr size, WGC3Denum access) {
667 return 0;
668 }
669
670 void WebGraphicsContext3DInProcessImpl::unmapBufferSubDataCHROMIUM(
671 const void* mem) {
672 }
673
674 void* WebGraphicsContext3DInProcessImpl::mapTexSubImage2DCHROMIUM(
675 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset,
676 WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type,
677 WGC3Denum access) {
678 return 0;
679 }
680
681 void WebGraphicsContext3DInProcessImpl::unmapTexSubImage2DCHROMIUM(
682 const void* mem) {
683 }
684
685 void WebGraphicsContext3DInProcessImpl::setVisibilityCHROMIUM(bool visible) {
686 }
687
688 void WebGraphicsContext3DInProcessImpl::
689 setMemoryAllocationChangedCallbackCHROMIUM(
690 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {
691 }
692
693 void WebGraphicsContext3DInProcessImpl::discardFramebufferEXT(
694 WGC3Denum target, WGC3Dsizei numAttachments, const WGC3Denum* attachments) {
695 }
696
697 void WebGraphicsContext3DInProcessImpl::discardBackbufferCHROMIUM() {
698 }
699
700 void WebGraphicsContext3DInProcessImpl::ensureBackbufferCHROMIUM() {
701 }
702
703 void WebGraphicsContext3DInProcessImpl::copyTextureToParentTextureCHROMIUM(
704 WebGLId id, WebGLId id2) {
705 NOTIMPLEMENTED();
706 }
707
708 void WebGraphicsContext3DInProcessImpl::bindUniformLocationCHROMIUM(
709 WebGLId program, WGC3Dint location, const WGC3Dchar* uniform) {
710 NOTIMPLEMENTED();
711 }
712
713 void WebGraphicsContext3DInProcessImpl::genMailboxCHROMIUM(
714 WGC3Dbyte* mailbox) {
715 NOTIMPLEMENTED();
716 }
717
718 void WebGraphicsContext3DInProcessImpl::produceTextureCHROMIUM(
719 WGC3Denum target, const WGC3Dbyte* mailbox) {
720 NOTIMPLEMENTED();
721 }
722
723 void WebGraphicsContext3DInProcessImpl::consumeTextureCHROMIUM(
724 WGC3Denum target, const WGC3Dbyte* mailbox) {
725 NOTIMPLEMENTED();
726 }
727
728 WebString WebGraphicsContext3DInProcessImpl::
729 getRequestableExtensionsCHROMIUM() {
730 return WebString();
731 }
732
733 void WebGraphicsContext3DInProcessImpl::requestExtensionCHROMIUM(const char*) {
734 }
735
736 void WebGraphicsContext3DInProcessImpl::blitFramebufferCHROMIUM(
737 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
738 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
739 WGC3Dbitfield mask, WGC3Denum filter) {
740 }
741
742 void WebGraphicsContext3DInProcessImpl::renderbufferStorageMultisampleCHROMIUM(
743 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat,
744 WGC3Dsizei width, WGC3Dsizei height) {
745 }
746
747 // Helper macros to reduce the amount of code.
748
749 #define DELEGATE_TO_GL(name, glname) \
750 void WebGraphicsContext3DInProcessImpl::name() { \
751 makeContextCurrent(); \
752 gl##glname(); \
753 }
754
755 #define DELEGATE_TO_GL_1(name, glname, t1) \
756 void WebGraphicsContext3DInProcessImpl::name(t1 a1) { \
757 makeContextCurrent(); \
758 gl##glname(a1); \
759 }
760
761 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \
762 rt WebGraphicsContext3DInProcessImpl::name(t1 a1) { \
763 makeContextCurrent(); \
764 return gl##glname(a1); \
765 }
766
767 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \
768 rt WebGraphicsContext3DInProcessImpl::name(t1 a1) { \
769 makeContextCurrent(); \
770 return gl##glname(a1) ? true : false; \
771 }
772
773 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \
774 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2) { \
775 makeContextCurrent(); \
776 gl##glname(a1, a2); \
777 }
778
779 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \
780 rt WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2) { \
781 makeContextCurrent(); \
782 return gl##glname(a1, a2); \
783 }
784
785 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \
786 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3) { \
787 makeContextCurrent(); \
788 gl##glname(a1, a2, a3); \
789 }
790
791 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \
792 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4) { \
793 makeContextCurrent(); \
794 gl##glname(a1, a2, a3, a4); \
795 }
796
797 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \
798 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
799 t5 a5) { \
800 makeContextCurrent(); \
801 gl##glname(a1, a2, a3, a4, a5); \
802 }
803
804 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \
805 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
806 t5 a5, t6 a6) { \
807 makeContextCurrent(); \
808 gl##glname(a1, a2, a3, a4, a5, a6); \
809 }
810
811 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \
812 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
813 t5 a5, t6 a6, t7 a7) { \
814 makeContextCurrent(); \
815 gl##glname(a1, a2, a3, a4, a5, a6, a7); \
816 }
817
818 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \
819 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
820 t5 a5, t6 a6, t7 a7, t8 a8) { \
821 makeContextCurrent(); \
822 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \
823 }
824
825 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
826 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
827 t5 a5, t6 a6, t7 a7, t8 a8, \
828 t9 a9) { \
829 makeContextCurrent(); \
830 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \
831 }
832
833 void WebGraphicsContext3DInProcessImpl::activeTexture(WGC3Denum texture) {
834 // FIXME: query number of textures available.
835 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32)
836 // FIXME: raise exception.
837 return;
838
839 makeContextCurrent();
840 glActiveTexture(texture);
841 }
842
843 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId)
844
845 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation,
846 WebGLId, WGC3Duint, const WGC3Dchar*)
847
848 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId);
849
850 void WebGraphicsContext3DInProcessImpl::bindFramebuffer(
851 WGC3Denum target, WebGLId framebuffer) {
852 makeContextCurrent();
853 if (!framebuffer)
854 framebuffer = (attributes_.antialias ? multisample_fbo_ : fbo_);
855 if (framebuffer != bound_fbo_) {
856 glBindFramebufferEXT(target, framebuffer);
857 bound_fbo_ = framebuffer;
858 }
859 }
860
861 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbufferEXT, WGC3Denum, WebGLId)
862
863 void WebGraphicsContext3DInProcessImpl::bindTexture(
864 WGC3Denum target, WebGLId texture) {
865 makeContextCurrent();
866 glBindTexture(target, texture);
867 bound_texture_ = texture;
868 }
869
870 DELEGATE_TO_GL_4(blendColor, BlendColor,
871 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
872
873 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum)
874
875 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate,
876 WGC3Denum, WGC3Denum)
877
878 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum)
879
880 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate,
881 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
882
883 DELEGATE_TO_GL_4(bufferData, BufferData,
884 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum)
885
886 DELEGATE_TO_GL_4(bufferSubData, BufferSubData,
887 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*)
888
889 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT,
890 WGC3Denum, WGC3Denum)
891
892 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield)
893
894 DELEGATE_TO_GL_4(clearColor, ClearColor,
895 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
896
897 DELEGATE_TO_GL_1(clearDepth, ClearDepth, WGC3Dclampf)
898
899 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint)
900
901 DELEGATE_TO_GL_4(colorMask, ColorMask,
902 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean)
903
904 void WebGraphicsContext3DInProcessImpl::compileShader(WebGLId shader) {
905 makeContextCurrent();
906
907 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
908 if (result == shader_source_map_.end()) {
909 // Passing down to gl driver to generate the correct error; or the case
910 // where the shader deletion is delayed when it's attached to a program.
911 glCompileShader(shader);
912 return;
913 }
914 ShaderSourceEntry* entry = result->second;
915 DCHECK(entry);
916
917 if (!AngleValidateShaderSource(entry)) {
918 // Shader didn't validate; don't move forward with compiling
919 // translated source.
920 return;
921 }
922
923 const char* translated_source = entry->translated_source.get();
924 int shader_length = translated_source ? strlen(translated_source) : 0;
925 glShaderSource(
926 shader, 1, const_cast<const char**>(&translated_source), &shader_length);
927 glCompileShader(shader);
928
929 #ifndef NDEBUG
930 int compileStatus;
931 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
932 // DCHECK that ANGLE generated GLSL will be accepted by OpenGL
933 DCHECK(compileStatus == GL_TRUE);
934 #endif
935 }
936
937 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D,
938 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
939 WGC3Dsizei, WGC3Dsizei, const void*)
940
941 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D,
942 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
943 WGC3Denum, WGC3Dsizei, const void*)
944
945 void WebGraphicsContext3DInProcessImpl::copyTexImage2D(
946 WGC3Denum target, WGC3Dint level, WGC3Denum internalformat, WGC3Dint x,
947 WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border) {
948 makeContextCurrent();
949
950 bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_);
951 if (needsResolve) {
952 ResolveMultisampledFramebuffer(x, y, width, height);
953 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
954 }
955
956 glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
957
958 if (needsResolve)
959 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
960 }
961
962 void WebGraphicsContext3DInProcessImpl::copyTexSubImage2D(
963 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset,
964 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) {
965 makeContextCurrent();
966
967 bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_);
968 if (needsResolve) {
969 ResolveMultisampledFramebuffer(x, y, width, height);
970 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
971 }
972
973 glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
974
975 if (needsResolve)
976 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
977 }
978
979 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum)
980
981 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum)
982
983 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean)
984
985 DELEGATE_TO_GL_2(depthRange, DepthRange, WGC3Dclampf, WGC3Dclampf)
986
987 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId)
988
989 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum)
990
991 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, WGC3Duint)
992
993 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei)
994
995 void WebGraphicsContext3DInProcessImpl::drawElements(
996 WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset) {
997 makeContextCurrent();
998 glDrawElements(mode, count, type,
999 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1000 }
1001
1002 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum)
1003
1004 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, WGC3Duint)
1005
1006 DELEGATE_TO_GL(finish, Finish)
1007
1008 DELEGATE_TO_GL(flush, Flush)
1009
1010 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbufferEXT,
1011 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId)
1012
1013 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT,
1014 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint)
1015
1016 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum)
1017
1018 void WebGraphicsContext3DInProcessImpl::generateMipmap(WGC3Denum target) {
1019 makeContextCurrent();
1020 if (is_gles2_ || have_ext_framebuffer_object_)
1021 glGenerateMipmapEXT(target);
1022 // FIXME: provide alternative code path? This will be unpleasant
1023 // to implement if glGenerateMipmapEXT is not available -- it will
1024 // require a texture readback and re-upload.
1025 }
1026
1027 bool WebGraphicsContext3DInProcessImpl::getActiveAttrib(
1028 WebGLId program, WGC3Duint index, ActiveInfo& info) {
1029 makeContextCurrent();
1030 if (!program) {
1031 synthesizeGLError(GL_INVALID_VALUE);
1032 return false;
1033 }
1034 GLint max_name_length = -1;
1035 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
1036 if (max_name_length < 0)
1037 return false;
1038 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
1039 GLsizei length = 0;
1040 GLint size = -1;
1041 GLenum type = 0;
1042 glGetActiveAttrib(program, index, max_name_length,
1043 &length, &size, &type, name.get());
1044 if (size < 0) {
1045 return false;
1046 }
1047 info.name = WebString::fromUTF8(name.get(), length);
1048 info.type = type;
1049 info.size = size;
1050 return true;
1051 }
1052
1053 bool WebGraphicsContext3DInProcessImpl::getActiveUniform(
1054 WebGLId program, WGC3Duint index, ActiveInfo& info) {
1055 makeContextCurrent();
1056 GLint max_name_length = -1;
1057 glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
1058 if (max_name_length < 0)
1059 return false;
1060 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
1061 GLsizei length = 0;
1062 GLint size = -1;
1063 GLenum type = 0;
1064 glGetActiveUniform(program, index, max_name_length,
1065 &length, &size, &type, name.get());
1066 if (size < 0) {
1067 return false;
1068 }
1069 info.name = WebString::fromUTF8(name.get(), length);
1070 info.type = type;
1071 info.size = size;
1072 return true;
1073 }
1074
1075 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders,
1076 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*)
1077
1078 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation,
1079 WebGLId, const WGC3Dchar*, WGC3Dint)
1080
1081 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv,
1082 WGC3Denum, WGC3Dboolean*)
1083
1084 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv,
1085 WGC3Denum, WGC3Denum, WGC3Dint*)
1086
1087 WebGraphicsContext3D::Attributes WebGraphicsContext3DInProcessImpl::
1088 getContextAttributes() {
1089 return attributes_;
1090 }
1091
1092 WGC3Denum WebGraphicsContext3DInProcessImpl::getError() {
1093 DCHECK(synthetic_errors_list_.size() == synthetic_errors_set_.size());
1094 if (!synthetic_errors_set_.empty()) {
1095 WGC3Denum error = synthetic_errors_list_.front();
1096 synthetic_errors_list_.pop_front();
1097 synthetic_errors_set_.erase(error);
1098 return error;
1099 }
1100
1101 makeContextCurrent();
1102 return glGetError();
1103 }
1104
1105 bool WebGraphicsContext3DInProcessImpl::isContextLost() {
1106 return false;
1107 }
1108
1109 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
1110
1111 void WebGraphicsContext3DInProcessImpl::getFramebufferAttachmentParameteriv(
1112 WGC3Denum target, WGC3Denum attachment,
1113 WGC3Denum pname, WGC3Dint* value) {
1114 makeContextCurrent();
1115 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
1116 attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT;
1117 // either works.
1118 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value);
1119 }
1120
1121 void WebGraphicsContext3DInProcessImpl::getIntegerv(
1122 WGC3Denum pname, WGC3Dint* value) {
1123 makeContextCurrent();
1124 if (is_gles2_) {
1125 glGetIntegerv(pname, value);
1126 return;
1127 }
1128 // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and
1129 // MAX_VARYING_VECTORS because desktop GL's corresponding queries
1130 // return the number of components whereas GLES2 return the number
1131 // of vectors (each vector has 4 components). Therefore, the value
1132 // returned by desktop GL needs to be divided by 4.
1133 switch (pname) {
1134 case MAX_FRAGMENT_UNIFORM_VECTORS:
1135 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value);
1136 *value /= 4;
1137 break;
1138 case MAX_VERTEX_UNIFORM_VECTORS:
1139 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value);
1140 *value /= 4;
1141 break;
1142 case MAX_VARYING_VECTORS:
1143 glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
1144 *value /= 4;
1145 break;
1146 default:
1147 glGetIntegerv(pname, value);
1148 }
1149 }
1150
1151 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*)
1152
1153 WebString WebGraphicsContext3DInProcessImpl::getProgramInfoLog(
1154 WebGLId program) {
1155 makeContextCurrent();
1156 GLint log_length;
1157 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
1158 if (!log_length)
1159 return WebString();
1160 scoped_ptr<GLchar[]> log(new GLchar[log_length]);
1161 GLsizei returned_log_length;
1162 glGetProgramInfoLog(program, log_length, &returned_log_length, log.get());
1163 DCHECK(log_length == returned_log_length + 1);
1164 WebString res = WebString::fromUTF8(log.get(), returned_log_length);
1165 return res;
1166 }
1167
1168 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT,
1169 WGC3Denum, WGC3Denum, WGC3Dint*)
1170
1171 void WebGraphicsContext3DInProcessImpl::getShaderiv(
1172 WebGLId shader, WGC3Denum pname, WGC3Dint* value) {
1173 makeContextCurrent();
1174
1175 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1176 if (result != shader_source_map_.end()) {
1177 ShaderSourceEntry* entry = result->second;
1178 DCHECK(entry);
1179 switch (pname) {
1180 case GL_COMPILE_STATUS:
1181 if (!entry->is_valid) {
1182 *value = 0;
1183 return;
1184 }
1185 break;
1186 case GL_INFO_LOG_LENGTH:
1187 if (!entry->is_valid) {
1188 *value = entry->log.get() ? strlen(entry->log.get()) : 0;
1189 if (*value)
1190 (*value)++;
1191 return;
1192 }
1193 break;
1194 case GL_SHADER_SOURCE_LENGTH:
1195 *value = entry->source.get() ? strlen(entry->source.get()) : 0;
1196 if (*value)
1197 (*value)++;
1198 return;
1199 }
1200 }
1201
1202 glGetShaderiv(shader, pname, value);
1203 }
1204
1205 void WebGraphicsContext3DInProcessImpl::getShaderPrecisionFormat(
1206 WGC3Denum shadertype, WGC3Denum precisiontype,
1207 WGC3Dint* range, WGC3Dint* precision) {
1208 switch (precisiontype) {
1209 case GL_LOW_INT:
1210 case GL_MEDIUM_INT:
1211 case GL_HIGH_INT:
1212 // These values are for a 32-bit twos-complement integer format.
1213 range[0] = 31;
1214 range[1] = 30;
1215 *precision = 0;
1216 break;
1217 case GL_LOW_FLOAT:
1218 case GL_MEDIUM_FLOAT:
1219 case GL_HIGH_FLOAT:
1220 // These values are for an IEEE single-precision floating-point format.
1221 range[0] = 127;
1222 range[1] = 127;
1223 *precision = 23;
1224 break;
1225 default:
1226 NOTREACHED();
1227 break;
1228 }
1229
1230 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
1231 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
1232 // This function is sometimes defined even though it's really just
1233 // a stub, so we need to set range and precision as if it weren't
1234 // defined before calling it.
1235 // On Mac OS with some GPUs, calling this generates a
1236 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
1237 // platforms.
1238 glGetShaderPrecisionFormat(shadertype, precisiontype,
1239 range, precision);
1240 }
1241 }
1242
1243 WebString WebGraphicsContext3DInProcessImpl::getShaderInfoLog(WebGLId shader) {
1244 makeContextCurrent();
1245
1246 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1247 if (result != shader_source_map_.end()) {
1248 ShaderSourceEntry* entry = result->second;
1249 DCHECK(entry);
1250 if (!entry->is_valid) {
1251 if (!entry->log)
1252 return WebString();
1253 WebString res = WebString::fromUTF8(
1254 entry->log.get(), strlen(entry->log.get()));
1255 return res;
1256 }
1257 }
1258
1259 GLint log_length = 0;
1260 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
1261 if (log_length <= 1)
1262 return WebString();
1263 scoped_ptr<GLchar[]> log(new GLchar[log_length]);
1264 GLsizei returned_log_length;
1265 glGetShaderInfoLog(shader, log_length, &returned_log_length, log.get());
1266 DCHECK(log_length == returned_log_length + 1);
1267 WebString res = WebString::fromUTF8(log.get(), returned_log_length);
1268 return res;
1269 }
1270
1271 WebString WebGraphicsContext3DInProcessImpl::getShaderSource(WebGLId shader) {
1272 makeContextCurrent();
1273
1274 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1275 if (result != shader_source_map_.end()) {
1276 ShaderSourceEntry* entry = result->second;
1277 DCHECK(entry);
1278 if (!entry->source)
1279 return WebString();
1280 WebString res = WebString::fromUTF8(
1281 entry->source.get(), strlen(entry->source.get()));
1282 return res;
1283 }
1284
1285 GLint log_length = 0;
1286 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &log_length);
1287 if (log_length <= 1)
1288 return WebString();
1289 scoped_ptr<GLchar[]> log(new GLchar[log_length]);
1290 GLsizei returned_log_length;
1291 glGetShaderSource(shader, log_length, &returned_log_length, log.get());
1292 DCHECK(log_length == returned_log_length + 1);
1293 WebString res = WebString::fromUTF8(log.get(), returned_log_length);
1294 return res;
1295 }
1296
1297 WebString WebGraphicsContext3DInProcessImpl::getString(WGC3Denum name) {
1298 makeContextCurrent();
1299 std::string result;
1300 if (name == GL_EXTENSIONS) {
1301 result = gl_context_->GetExtensions();
1302 if (!is_gles2_) {
1303 std::vector<std::string> split;
1304 base::SplitString(result, ' ', &split);
1305 if (std::find(split.begin(), split.end(), "GL_EXT_bgra") != split.end()) {
1306 // If we support GL_EXT_bgra, pretend we support a couple of GLES2
1307 // extension that are a subset of it.
1308 result += " GL_EXT_texture_format_BGRA8888 GL_EXT_read_format_bgra";
1309 }
1310 }
1311 std::string surface_extensions = gl_surface_->GetExtensions();
1312 if (!surface_extensions.empty())
1313 result += " " + surface_extensions;
1314 } else {
1315 result = reinterpret_cast<const char*>(glGetString(name));
1316 }
1317 return WebString::fromUTF8(result.c_str());
1318 }
1319
1320 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv,
1321 WGC3Denum, WGC3Denum, WGC3Dfloat*)
1322
1323 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv,
1324 WGC3Denum, WGC3Denum, WGC3Dint*)
1325
1326 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*)
1327
1328 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*)
1329
1330 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation,
1331 WebGLId, const WGC3Dchar*, WGC3Dint)
1332
1333 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv,
1334 WGC3Duint, WGC3Denum, WGC3Dfloat*)
1335
1336 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv,
1337 WGC3Duint, WGC3Denum, WGC3Dint*)
1338
1339 WGC3Dsizeiptr WebGraphicsContext3DInProcessImpl::getVertexAttribOffset(
1340 WGC3Duint index, WGC3Denum pname) {
1341 makeContextCurrent();
1342 void* pointer;
1343 glGetVertexAttribPointerv(index, pname, &pointer);
1344 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer));
1345 }
1346
1347 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum)
1348
1349 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean)
1350
1351 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean)
1352
1353 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebufferEXT, WebGLId, WGC3Dboolean)
1354
1355 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean)
1356
1357 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbufferEXT, WebGLId, WGC3Dboolean)
1358
1359 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean)
1360
1361 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean)
1362
1363 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat)
1364
1365 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId)
1366
1367 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint)
1368
1369 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat)
1370
1371 void WebGraphicsContext3DInProcessImpl::readPixels(
1372 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height,
1373 WGC3Denum format, WGC3Denum type, void* pixels) {
1374 makeContextCurrent();
1375 // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
1376 // all previous rendering calls should be done before reading pixels.
1377 glFlush();
1378 bool needs_resolve =
1379 (attributes_.antialias && bound_fbo_ == multisample_fbo_);
1380 if (needs_resolve) {
1381 ResolveMultisampledFramebuffer(x, y, width, height);
1382 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
1383 glFlush();
1384 }
1385
1386 glReadPixels(x, y, width, height, format, type, pixels);
1387
1388 if (needs_resolve)
1389 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
1390 }
1391
1392 void WebGraphicsContext3DInProcessImpl::releaseShaderCompiler() {
1393 }
1394
1395 void WebGraphicsContext3DInProcessImpl::renderbufferStorage(
1396 WGC3Denum target,
1397 WGC3Denum internalformat,
1398 WGC3Dsizei width,
1399 WGC3Dsizei height) {
1400 makeContextCurrent();
1401 if (!is_gles2_) {
1402 switch (internalformat) {
1403 case GL_DEPTH_STENCIL:
1404 internalformat = GL_DEPTH24_STENCIL8_EXT;
1405 break;
1406 case GL_DEPTH_COMPONENT16:
1407 internalformat = GL_DEPTH_COMPONENT;
1408 break;
1409 case GL_RGBA4:
1410 case GL_RGB5_A1:
1411 internalformat = GL_RGBA;
1412 break;
1413 case 0x8D62: // GL_RGB565
1414 internalformat = GL_RGB;
1415 break;
1416 }
1417 }
1418 glRenderbufferStorageEXT(target, internalformat, width, height);
1419 }
1420
1421 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dclampf, WGC3Dboolean)
1422
1423 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1424
1425 void WebGraphicsContext3DInProcessImpl::texImage2D(
1426 WGC3Denum target, WGC3Dint level, WGC3Denum internalFormat,
1427 WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border,
1428 WGC3Denum format, WGC3Denum type, const void* pixels) {
1429 makeContextCurrent();
1430 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
1431 if (format == GL_BGRA_EXT && internalFormat == GL_BGRA_EXT) {
1432 internalFormat = GL_RGBA;
1433 } else if (type == GL_FLOAT) {
1434 if (format == GL_RGBA) {
1435 internalFormat = GL_RGBA32F_ARB;
1436 } else if (format == GL_RGB) {
1437 internalFormat = GL_RGB32F_ARB;
1438 }
1439 }
1440 }
1441 glTexImage2D(target, level, internalFormat,
1442 width, height, border, format, type, pixels);
1443 }
1444
1445 void WebGraphicsContext3DInProcessImpl::shaderSource(
1446 WebGLId shader, const WGC3Dchar* source) {
1447 makeContextCurrent();
1448 GLint length = source ? strlen(source) : 0;
1449 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1450 if (result != shader_source_map_.end()) {
1451 ShaderSourceEntry* entry = result->second;
1452 DCHECK(entry);
1453 entry->source.reset(new char[length + 1]);
1454 if (source)
1455 memcpy(entry->source.get(), source, (length + 1) * sizeof(char));
1456 else
1457 entry->source[0] = '\0';
1458 } else {
1459 glShaderSource(shader, 1, &source, &length);
1460 }
1461 }
1462
1463 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint)
1464
1465 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate,
1466 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint)
1467
1468 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint)
1469
1470 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate,
1471 WGC3Denum, WGC3Duint)
1472
1473 DELEGATE_TO_GL_3(stencilOp, StencilOp,
1474 WGC3Denum, WGC3Denum, WGC3Denum)
1475
1476 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate,
1477 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
1478
1479 DELEGATE_TO_GL_3(texParameterf, TexParameterf, WGC3Denum, WGC3Denum, WGC3Dfloat)
1480
1481 DELEGATE_TO_GL_3(texParameteri, TexParameteri, WGC3Denum, WGC3Denum, WGC3Dint)
1482
1483 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D,
1484 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
1485 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
1486
1487 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat)
1488
1489 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv,
1490 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1491
1492 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint)
1493
1494 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1495
1496 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat)
1497
1498 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv,
1499 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1500
1501 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint)
1502
1503 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1504
1505 DELEGATE_TO_GL_4(uniform3f, Uniform3f,
1506 WGC3Dint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1507
1508 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv,
1509 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1510
1511 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1512
1513 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1514
1515 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint,
1516 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1517
1518 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv,
1519 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1520
1521 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint,
1522 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1523
1524 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1525
1526 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv,
1527 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1528
1529 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv,
1530 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1531
1532 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv,
1533 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1534
1535 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId)
1536
1537 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId)
1538
1539 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat)
1540
1541 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, const WGC3Dfloat*)
1542
1543 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f,
1544 WGC3Duint, WGC3Dfloat, WGC3Dfloat)
1545
1546 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, const WGC3Dfloat*)
1547
1548 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f,
1549 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1550
1551 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, const WGC3Dfloat*)
1552
1553 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f,
1554 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1555
1556 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, const WGC3Dfloat*)
1557
1558 void WebGraphicsContext3DInProcessImpl::vertexAttribPointer(
1559 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized,
1560 WGC3Dsizei stride, WGC3Dintptr offset) {
1561 makeContextCurrent();
1562 glVertexAttribPointer(index, size, type, normalized, stride,
1563 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1564 }
1565
1566 DELEGATE_TO_GL_4(viewport, Viewport, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1567
1568 WebGLId WebGraphicsContext3DInProcessImpl::createBuffer() {
1569 makeContextCurrent();
1570 GLuint o = 0;
1571 glGenBuffersARB(1, &o);
1572 return o;
1573 }
1574
1575 WebGLId WebGraphicsContext3DInProcessImpl::createFramebuffer() {
1576 makeContextCurrent();
1577 GLuint o = 0;
1578 glGenFramebuffersEXT(1, &o);
1579 return o;
1580 }
1581
1582 WebGLId WebGraphicsContext3DInProcessImpl::createProgram() {
1583 makeContextCurrent();
1584 return glCreateProgram();
1585 }
1586
1587 WebGLId WebGraphicsContext3DInProcessImpl::createRenderbuffer() {
1588 makeContextCurrent();
1589 GLuint o = 0;
1590 glGenRenderbuffersEXT(1, &o);
1591 return o;
1592 }
1593
1594 WebGLId WebGraphicsContext3DInProcessImpl::createShader(
1595 WGC3Denum shaderType) {
1596 makeContextCurrent();
1597 DCHECK(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER);
1598 GLuint shader = glCreateShader(shaderType);
1599 if (shader) {
1600 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1601 if (result != shader_source_map_.end()) {
1602 delete result->second;
1603 shader_source_map_.erase(result);
1604 }
1605 shader_source_map_.insert(
1606 ShaderSourceMap::value_type(shader, new ShaderSourceEntry(shaderType)));
1607 }
1608
1609 return shader;
1610 }
1611
1612 WebGLId WebGraphicsContext3DInProcessImpl::createTexture() {
1613 makeContextCurrent();
1614 GLuint o = 0;
1615 glGenTextures(1, &o);
1616 return o;
1617 }
1618
1619 void WebGraphicsContext3DInProcessImpl::deleteBuffer(WebGLId buffer) {
1620 makeContextCurrent();
1621 glDeleteBuffersARB(1, &buffer);
1622 }
1623
1624 void WebGraphicsContext3DInProcessImpl::deleteFramebuffer(
1625 WebGLId framebuffer) {
1626 makeContextCurrent();
1627 glDeleteFramebuffersEXT(1, &framebuffer);
1628 }
1629
1630 void WebGraphicsContext3DInProcessImpl::deleteProgram(WebGLId program) {
1631 makeContextCurrent();
1632 glDeleteProgram(program);
1633 }
1634
1635 void WebGraphicsContext3DInProcessImpl::deleteRenderbuffer(
1636 WebGLId renderbuffer) {
1637 makeContextCurrent();
1638 glDeleteRenderbuffersEXT(1, &renderbuffer);
1639 }
1640
1641 void WebGraphicsContext3DInProcessImpl::deleteShader(WebGLId shader) {
1642 makeContextCurrent();
1643
1644 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1645 if (result != shader_source_map_.end()) {
1646 delete result->second;
1647 shader_source_map_.erase(result);
1648 }
1649 glDeleteShader(shader);
1650 }
1651
1652 void WebGraphicsContext3DInProcessImpl::deleteTexture(WebGLId texture) {
1653 makeContextCurrent();
1654 glDeleteTextures(1, &texture);
1655 }
1656
1657 WGC3Denum WebGraphicsContext3DInProcessImpl::getGraphicsResetStatusARB() {
1658 // TODO(kbr): this implementation doesn't support lost contexts yet.
1659 return GL_NO_ERROR;
1660 }
1661
1662 void WebGraphicsContext3DInProcessImpl::texImageIOSurface2DCHROMIUM(
1663 WGC3Denum target, WGC3Dint width, WGC3Dint height,
1664 WGC3Duint ioSurfaceId, WGC3Duint plane) {
1665 }
1666
1667 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT,
1668 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint)
1669
1670 WebGLId WebGraphicsContext3DInProcessImpl::createQueryEXT() {
1671 makeContextCurrent();
1672 GLuint o = 0;
1673 glGenQueriesARB(1, &o);
1674 return o;
1675 }
1676
1677 void WebGraphicsContext3DInProcessImpl::deleteQueryEXT(WebGLId query) {
1678 makeContextCurrent();
1679 glDeleteQueriesARB(1, &query);
1680 }
1681
1682 DELEGATE_TO_GL_1R(isQueryEXT, IsQueryARB, WebGLId, WGC3Dboolean)
1683 DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryARB, WGC3Denum, WebGLId)
1684 DELEGATE_TO_GL_1(endQueryEXT, EndQueryARB, WGC3Denum)
1685 DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivARB, WGC3Denum, WGC3Denum, WGC3Dint*)
1686 DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivARB,
1687 WebGLId, WGC3Denum, WGC3Duint*)
1688
1689 void WebGraphicsContext3DInProcessImpl::copyTextureCHROMIUM(
1690 WGC3Denum, WGC3Duint, WGC3Duint, WGC3Dint, WGC3Denum, WGC3Denum) {
1691 NOTIMPLEMENTED();
1692 }
1693
1694 void WebGraphicsContext3DInProcessImpl::bindTexImage2DCHROMIUM(
1695 WGC3Denum target, WGC3Dint imageId) {
1696 NOTIMPLEMENTED();
1697 }
1698
1699 void WebGraphicsContext3DInProcessImpl::releaseTexImage2DCHROMIUM(
1700 WGC3Denum target, WGC3Dint imageId) {
1701 NOTIMPLEMENTED();
1702 }
1703
1704 void* WebGraphicsContext3DInProcessImpl::mapBufferCHROMIUM(
1705 WGC3Denum target, WGC3Denum access) {
1706 return 0;
1707 }
1708
1709 WGC3Dboolean WebGraphicsContext3DInProcessImpl::unmapBufferCHROMIUM(
1710 WGC3Denum target) {
1711 return false;
1712 }
1713
1714 void WebGraphicsContext3DInProcessImpl::drawBuffersEXT(
1715 WGC3Dsizei n, const WGC3Denum* bufs) {
1716 NOTIMPLEMENTED();
1717 }
1718
1719 GrGLInterface* WebGraphicsContext3DInProcessImpl::onCreateGrGLInterface() {
1720 return gfx::CreateInProcessSkiaGLBinding();
1721 }
1722
1723 bool WebGraphicsContext3DInProcessImpl::AngleCreateCompilers() {
1724 if (!ShInitialize())
1725 return false;
1726
1727 ShBuiltInResources resources;
1728 ShInitBuiltInResources(&resources);
1729 getIntegerv(GL_MAX_VERTEX_ATTRIBS, &resources.MaxVertexAttribs);
1730 getIntegerv(MAX_VERTEX_UNIFORM_VECTORS, &resources.MaxVertexUniformVectors);
1731 getIntegerv(MAX_VARYING_VECTORS, &resources.MaxVaryingVectors);
1732 getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
1733 &resources.MaxVertexTextureImageUnits);
1734 getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
1735 &resources.MaxCombinedTextureImageUnits);
1736 getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &resources.MaxTextureImageUnits);
1737 getIntegerv(MAX_FRAGMENT_UNIFORM_VECTORS,
1738 &resources.MaxFragmentUniformVectors);
1739 // Always set to 1 for OpenGL ES.
1740 resources.MaxDrawBuffers = 1;
1741
1742 resources.OES_standard_derivatives = have_ext_oes_standard_derivatives_;
1743 resources.OES_EGL_image_external = have_ext_oes_egl_image_external_;
1744
1745 fragment_compiler_ = ShConstructCompiler(
1746 SH_FRAGMENT_SHADER, SH_WEBGL_SPEC,
1747 is_gles2_ ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT, &resources);
1748 vertex_compiler_ = ShConstructCompiler(
1749 SH_VERTEX_SHADER, SH_WEBGL_SPEC,
1750 is_gles2_ ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT, &resources);
1751 return (fragment_compiler_ && vertex_compiler_);
1752 }
1753
1754 void WebGraphicsContext3DInProcessImpl::AngleDestroyCompilers() {
1755 if (fragment_compiler_) {
1756 ShDestruct(fragment_compiler_);
1757 fragment_compiler_ = 0;
1758 }
1759 if (vertex_compiler_) {
1760 ShDestruct(vertex_compiler_);
1761 vertex_compiler_ = 0;
1762 }
1763 }
1764
1765 bool WebGraphicsContext3DInProcessImpl::AngleValidateShaderSource(
1766 ShaderSourceEntry* entry) {
1767 entry->is_valid = false;
1768 entry->translated_source.reset();
1769 entry->log.reset();
1770
1771 ShHandle compiler = 0;
1772 switch (entry->type) {
1773 case GL_FRAGMENT_SHADER:
1774 compiler = fragment_compiler_;
1775 break;
1776 case GL_VERTEX_SHADER:
1777 compiler = vertex_compiler_;
1778 break;
1779 }
1780 if (!compiler)
1781 return false;
1782
1783 char* source = entry->source.get();
1784 if (!ShCompile(compiler, &source, 1, SH_OBJECT_CODE)) {
1785 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
1786 int logSize = 0;
1787 #else
1788 size_t logSize = 0;
1789 #endif
1790 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &logSize);
1791 if (logSize > 1) {
1792 entry->log.reset(new char[logSize]);
1793 ShGetInfoLog(compiler, entry->log.get());
1794 }
1795 return false;
1796 }
1797
1798 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
1799 int length = 0;
1800 #else
1801 size_t length = 0;
1802 #endif
1803 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length);
1804 if (length > 1) {
1805 entry->translated_source.reset(new char[length]);
1806 ShGetObjectCode(compiler, entry->translated_source.get());
1807 }
1808 entry->is_valid = true;
1809 return true;
1810 }
1811
1812 } // namespace gpu
1813 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/gpu/webgraphicscontext3d_in_process_impl.h ('k') | webkit/gpu/webgraphicscontext3d_provider_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698