summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/common/gpu/image_transport_surface_calayer_mac.h10
-rw-r--r--content/common/gpu/image_transport_surface_calayer_mac.mm239
-rw-r--r--content/common/gpu/image_transport_surface_fbo_mac.mm48
-rw-r--r--content/common/gpu/image_transport_surface_iosurface_mac.h1
-rw-r--r--content/common/gpu/image_transport_surface_mac.mm13
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py13
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc1
-rw-r--r--gpu/command_buffer/service/context_group.cc9
-rw-r--r--gpu/command_buffer/service/context_state_impl_autogen.h8
-rw-r--r--gpu/command_buffer/service/feature_info.cc69
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc20
-rw-r--r--gpu/command_buffer/service/framebuffer_manager_unittest.cc100
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc124
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc17
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc5
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc4
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.cc10
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.h6
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager_unittest.cc47
-rw-r--r--gpu/command_buffer/service/shader_translator.cc12
-rw-r--r--gpu/command_buffer/service/test_helper.cc82
-rw-r--r--gpu/command_buffer/service/test_helper.h5
-rwxr-xr-xui/gl/generate_bindings.py23
-rw-r--r--ui/gl/gl_bindings_autogen_gl.cc12
-rw-r--r--ui/gl/gl_bindings_autogen_gl.h1
-rw-r--r--ui/gl/gl_context.cc23
-rw-r--r--ui/gl/gl_context_cgl.cc9
-rw-r--r--ui/gl/gl_context_mac.mm1
-rw-r--r--ui/gl/gl_gl_api_implementation.cc9
-rw-r--r--ui/gl/gl_implementation.cc1
-rw-r--r--ui/gl/gl_implementation.h1
-rw-r--r--ui/gl/gl_implementation_mac.cc7
-rw-r--r--ui/gl/gl_surface_mac.cc3
-rw-r--r--ui/gl/gl_version_info.cc65
-rw-r--r--ui/gl/gl_version_info.h20
35 files changed, 772 insertions, 246 deletions
diff --git a/content/common/gpu/image_transport_surface_calayer_mac.h b/content/common/gpu/image_transport_surface_calayer_mac.h
index 47aaeb0..bb7c3a8 100644
--- a/content/common/gpu/image_transport_surface_calayer_mac.h
+++ b/content/common/gpu/image_transport_surface_calayer_mac.h
@@ -8,7 +8,6 @@
#include "base/mac/scoped_nsobject.h"
#include "content/common/gpu/image_transport_surface_fbo_mac.h"
#include "ui/base/cocoa/remote_layer_api.h"
-#include "ui/gl/gl_bindings.h"
#include "ui/gl/gpu_switching_observer.h"
#include "ui/gl/scoped_cgl.h"
@@ -78,6 +77,15 @@ class CALayerStorageProvider
gfx::Size fbo_pixel_size_;
float fbo_scale_factor_;
+ // State for the Core Profile code path.
+ GLuint program_;
+ GLuint vertex_shader_;
+ GLuint fragment_shader_;
+ GLuint position_location_;
+ GLuint tex_location_;
+ GLuint vertex_buffer_;
+ GLuint vertex_array_;
+
// The CALayer that the current frame is being drawn into.
base::scoped_nsobject<CAContext> context_;
base::scoped_nsobject<ImageTransportLayer> layer_;
diff --git a/content/common/gpu/image_transport_surface_calayer_mac.mm b/content/common/gpu/image_transport_surface_calayer_mac.mm
index afcfc56..88e85b2 100644
--- a/content/common/gpu/image_transport_surface_calayer_mac.mm
+++ b/content/common/gpu/image_transport_surface_calayer_mac.mm
@@ -104,6 +104,13 @@ CALayerStorageProvider::CALayerStorageProvider(
can_draw_returned_false_count_(0),
fbo_texture_(0),
fbo_scale_factor_(1),
+ program_(0),
+ vertex_shader_(0),
+ fragment_shader_(0),
+ position_location_(0),
+ tex_location_(0),
+ vertex_buffer_(0),
+ vertex_array_(0),
recreate_layer_after_gpu_switch_(false),
pending_draw_weak_factory_(this) {
ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
@@ -126,16 +133,109 @@ bool CALayerStorageProvider::AllocateColorBufferStorage(
LOG(ERROR) << "OpenGL error hit but ignored before allocating buffer "
<< "storage: " << error;
}
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
- 0,
- GL_RGBA,
- pixel_size.width(),
- pixel_size.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- NULL);
- glFlush();
+
+ if (gfx::GetGLImplementation() ==
+ gfx::kGLImplementationDesktopGLCoreProfile) {
+ glTexImage2D(GL_TEXTURE_2D,
+ 0,
+ GL_RGBA,
+ pixel_size.width(),
+ pixel_size.height(),
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ NULL);
+ glFlush();
+
+ if (!vertex_shader_) {
+ const char* source =
+ "#version 150\n"
+ "in vec4 position;\n"
+ "out vec2 texcoord;\n"
+ "void main() {\n"
+ " texcoord = vec2(position.x, position.y);\n"
+ " gl_Position = vec4(2*position.x-1, 2*position.y-1,\n"
+ " position.z, position.w);\n"
+ "}\n";
+ vertex_shader_ = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertex_shader_, 1, &source, NULL);
+ glCompileShader(vertex_shader_);
+#if DCHECK_IS_ON()
+ GLint status = GL_FALSE;
+ glGetShaderiv(vertex_shader_, GL_COMPILE_STATUS, &status);
+ DCHECK(status == GL_TRUE);
+#endif
+ }
+ if (!fragment_shader_) {
+ const char* source =
+ "#version 150\n"
+ "uniform sampler2D tex;\n"
+ "in vec2 texcoord;\n"
+ "out vec4 frag_color;\n"
+ "void main() {\n"
+ " frag_color = texture(tex, texcoord);\n"
+ "}\n";
+ fragment_shader_ = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragment_shader_, 1, &source, NULL);
+ glCompileShader(fragment_shader_);
+#if DCHECK_IS_ON()
+ GLint status = GL_FALSE;
+ glGetShaderiv(fragment_shader_, GL_COMPILE_STATUS, &status);
+ DCHECK(status == GL_TRUE);
+#endif
+ }
+ if (!program_) {
+ program_ = glCreateProgram();
+ glAttachShader(program_, vertex_shader_);
+ glAttachShader(program_, fragment_shader_);
+ glBindFragDataLocation(program_, 0, "frag_color");
+ glLinkProgram(program_);
+#if DCHECK_IS_ON()
+ GLint status = GL_FALSE;
+ glGetProgramiv(program_, GL_LINK_STATUS, &status);
+ DCHECK(status == GL_TRUE);
+#endif
+ position_location_ = glGetAttribLocation(program_, "position");
+ tex_location_ = glGetUniformLocation(program_, "tex");
+ }
+ if (!vertex_buffer_) {
+ GLfloat vertex_data[24] = {
+ 0, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 1, 0, 1,
+ 1, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 0, 0, 1,
+ };
+ glGenBuffersARB(1, &vertex_buffer_);
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
+ vertex_data, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ if (!vertex_array_) {
+ glGenVertexArraysOES(1, &vertex_array_);
+ glBindVertexArrayOES(vertex_array_);
+ {
+ glEnableVertexAttribArray(position_location_);
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
+ glVertexAttribPointer(position_location_, 4, GL_FLOAT, GL_FALSE, 0, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ glBindVertexArrayOES(0);
+ }
+ } else {
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
+ 0,
+ GL_RGBA,
+ pixel_size.width(),
+ pixel_size.height(),
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ NULL);
+ glFlush();
+ }
bool hit_error = false;
while ((error = glGetError()) != GL_NO_ERROR) {
@@ -157,6 +257,25 @@ bool CALayerStorageProvider::AllocateColorBufferStorage(
}
void CALayerStorageProvider::FreeColorBufferStorage() {
+ if (gfx::GetGLImplementation() ==
+ gfx::kGLImplementationDesktopGLCoreProfile) {
+ if (vertex_shader_)
+ glDeleteShader(vertex_shader_);
+ if (fragment_shader_)
+ glDeleteShader(fragment_shader_);
+ if (program_)
+ glDeleteProgram(program_);
+ if (vertex_buffer_)
+ glDeleteBuffersARB(1, &vertex_buffer_);
+ if (vertex_array_)
+ glDeleteVertexArraysOES(1, &vertex_array_);
+ vertex_shader_ = 0;
+ fragment_shader_ = 0;
+ program_ = 0;
+ vertex_buffer_ = 0;
+ vertex_array_ = 0;
+ }
+
// Note that |context_| still holds a reference to |layer_|, and will until
// a new frame is swapped in.
[layer_ resetStorageProvider];
@@ -313,45 +432,69 @@ bool CALayerStorageProvider::LayerCanDraw() {
}
void CALayerStorageProvider::LayerDoDraw() {
- GLint viewport[4] = {0, 0, 0, 0};
- glGetIntegerv(GL_VIEWPORT, viewport);
- gfx::Size viewport_size(viewport[2], viewport[3]);
-
- // Set the coordinate system to be one-to-one with pixels.
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, viewport_size.width(), 0, viewport_size.height(), -1, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- // Reset drawing state and draw a fullscreen quad.
- glUseProgram(0);
- glDisable(GL_BLEND);
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_SCISSOR_TEST);
- glColor4f(1, 1, 1, 1);
- glActiveTexture(GL_TEXTURE0);
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fbo_texture_);
- glBegin(GL_QUADS);
- {
- glTexCoord2f(0, 0);
- glVertex2f(0, 0);
-
- glTexCoord2f(0, fbo_pixel_size_.height());
- glVertex2f(0, fbo_pixel_size_.height());
-
- glTexCoord2f(fbo_pixel_size_.width(), fbo_pixel_size_.height());
- glVertex2f(fbo_pixel_size_.width(), fbo_pixel_size_.height());
-
- glTexCoord2f(fbo_pixel_size_.width(), 0);
- glVertex2f(fbo_pixel_size_.width(), 0);
+ if (gfx::GetGLImplementation() ==
+ gfx::kGLImplementationDesktopGLCoreProfile) {
+ glClearColor(1, 0, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDisable(GL_BLEND);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_SCISSOR_TEST);
+
+ DCHECK(glIsProgram(program_));
+ glUseProgram(program_);
+ glBindVertexArrayOES(vertex_array_);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, fbo_texture_);
+ glUniform1i(tex_location_, 0);
+
+ glDisable(GL_CULL_FACE);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ glBindVertexArrayOES(0);
+ glUseProgram(0);
+ } else {
+ GLint viewport[4] = {0, 0, 0, 0};
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ gfx::Size viewport_size(viewport[2], viewport[3]);
+
+ // Set the coordinate system to be one-to-one with pixels.
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, viewport_size.width(), 0, viewport_size.height(), -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // Reset drawing state and draw a fullscreen quad.
+ glUseProgram(0);
+ glDisable(GL_BLEND);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glColor4f(1, 1, 1, 1);
+ glActiveTexture(GL_TEXTURE0);
+ glEnable(GL_TEXTURE_RECTANGLE_ARB);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fbo_texture_);
+ glBegin(GL_QUADS);
+ {
+ glTexCoord2f(0, 0);
+ glVertex2f(0, 0);
+
+ glTexCoord2f(0, fbo_pixel_size_.height());
+ glVertex2f(0, fbo_pixel_size_.height());
+
+ glTexCoord2f(fbo_pixel_size_.width(), fbo_pixel_size_.height());
+ glVertex2f(fbo_pixel_size_.width(), fbo_pixel_size_.height());
+
+ glTexCoord2f(fbo_pixel_size_.width(), 0);
+ glVertex2f(fbo_pixel_size_.width(), 0);
+ }
+ glEnd();
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+ glDisable(GL_TEXTURE_RECTANGLE_ARB);
}
- glEnd();
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- glDisable(GL_TEXTURE_RECTANGLE_ARB);
GLint current_renderer_id = 0;
if (CGLGetParameter(CGLGetCurrentContext(),
diff --git a/content/common/gpu/image_transport_surface_fbo_mac.mm b/content/common/gpu/image_transport_surface_fbo_mac.mm
index 95a09f9..cb4e3a0 100644
--- a/content/common/gpu/image_transport_surface_fbo_mac.mm
+++ b/content/common/gpu/image_transport_surface_fbo_mac.mm
@@ -15,6 +15,13 @@
namespace content {
+scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
+ GpuChannelManager* manager,
+ GpuCommandBufferStub* stub,
+ gfx::PluginWindowHandle handle) {
+ return new ImageTransportSurfaceFBO(manager, stub, handle);
+}
+
ImageTransportSurfaceFBO::ImageTransportSurfaceFBO(
GpuChannelManager* manager,
GpuCommandBufferStub* stub,
@@ -43,7 +50,9 @@ bool ImageTransportSurfaceFBO::Initialize() {
// Only support IOSurfaces if the GL implementation is the native desktop GL.
// IO surfaces will not work with, for example, OSMesa software renderer
// GL contexts.
- if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL &&
+ if (gfx::GetGLImplementation() !=
+ gfx::kGLImplementationDesktopGLCoreProfile &&
+ gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL &&
gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL)
return false;
@@ -116,8 +125,13 @@ void ImageTransportSurfaceFBO::NotifyWasBound() {
glUseProgram(0);
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
DCHECK(status == GL_FRAMEBUFFER_COMPLETE);
- glBegin(GL_TRIANGLES);
- glEnd();
+ if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
+ // These aren't present in the core profile.
+ // TODO(ccameron): verify this workaround isn't still needed with
+ // the core profile.
+ glBegin(GL_TRIANGLES);
+ glEnd();
+ }
glUseProgram(old_program);
}
@@ -298,7 +312,19 @@ void ImageTransportSurfaceFBO::AllocateOrResizeFramebuffer(
// GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
// Mac OS X and is required for IOSurface interoperability.
GLint previous_texture_id = 0;
- glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id);
+
+ GLenum texture_target = GL_TEXTURE_RECTANGLE_ARB;
+ GLenum texture_binding_target = GL_TEXTURE_BINDING_RECTANGLE_ARB;
+ // However, the remote core animation path on the core profile will
+ // be the preferred combination going forward.
+ if (gfx::GetGLImplementation() ==
+ gfx::kGLImplementationDesktopGLCoreProfile &&
+ ui::RemoteLayerAPISupported()) {
+ texture_target = GL_TEXTURE_2D;
+ texture_binding_target = GL_TEXTURE_BINDING_2D;
+ }
+
+ glGetIntegerv(texture_binding_target, &previous_texture_id);
// Free the old IO Surface first to reduce memory fragmentation.
DestroyFramebuffer();
@@ -308,17 +334,17 @@ void ImageTransportSurfaceFBO::AllocateOrResizeFramebuffer(
glGenTextures(1, &texture_id_);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id_);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
+ glBindTexture(texture_target, texture_id_);
+ glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(texture_target,
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
+ glTexParameteri(texture_target,
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_RECTANGLE_ARB,
+ texture_target,
texture_id_,
0);
@@ -373,7 +399,7 @@ void ImageTransportSurfaceFBO::AllocateOrResizeFramebuffer(
has_complete_framebuffer_ = true;
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_id);
+ glBindTexture(texture_target, previous_texture_id);
// The FBO remains bound for this GL context.
}
diff --git a/content/common/gpu/image_transport_surface_iosurface_mac.h b/content/common/gpu/image_transport_surface_iosurface_mac.h
index d25f91f..797c4ec 100644
--- a/content/common/gpu/image_transport_surface_iosurface_mac.h
+++ b/content/common/gpu/image_transport_surface_iosurface_mac.h
@@ -8,7 +8,6 @@
#include <list>
#include "content/common/gpu/image_transport_surface_fbo_mac.h"
-#include "ui/gl/gl_bindings.h"
// Note that this must be included after gl_bindings.h to avoid conflicts.
#include <OpenGL/CGLIOSurface.h>
diff --git a/content/common/gpu/image_transport_surface_mac.mm b/content/common/gpu/image_transport_surface_mac.mm
index 0f40f23..7966d5a 100644
--- a/content/common/gpu/image_transport_surface_mac.mm
+++ b/content/common/gpu/image_transport_surface_mac.mm
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/gpu/image_transport_surface_fbo_mac.h"
+#include "content/common/gpu/image_transport_surface.h"
#include "content/common/gpu/gpu_messages.h"
#include "ui/gfx/native_widget_types.h"
@@ -11,6 +11,12 @@
#include "ui/gl/gl_surface_osmesa.h"
namespace content {
+
+scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
+ GpuChannelManager* manager,
+ GpuCommandBufferStub* stub,
+ gfx::PluginWindowHandle handle);
+
namespace {
// A subclass of GLSurfaceOSMesa that doesn't print an error message when
@@ -47,9 +53,10 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
switch (gfx::GetGLImplementation()) {
case gfx::kGLImplementationDesktopGL:
+ case gfx::kGLImplementationDesktopGLCoreProfile:
case gfx::kGLImplementationAppleGL:
- return scoped_refptr<gfx::GLSurface>(new ImageTransportSurfaceFBO(
- manager, stub, surface_handle.handle));
+ return ImageTransportSurfaceCreateNativeSurface(manager, stub,
+ surface_handle.handle);
default:
// Content shell in DRT mode spins up a gpu process which needs an
// image transport surface, but that surface isn't used to read pixel
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index aa7be79..0407033 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -386,7 +386,8 @@ _STATES = {
'name': 'hint_generate_mipmap',
'type': 'GLenum',
'enum': 'GL_GENERATE_MIPMAP_HINT',
- 'default': 'GL_DONT_CARE'
+ 'default': 'GL_DONT_CARE',
+ 'gl_version_flag': '!is_desktop_core_profile'
},
{
'name': 'hint_fragment_shader_derivative',
@@ -9652,11 +9653,21 @@ void ContextState::InitState(const ContextState *prev_state) const {
else:
file.Write(" if (prev_state->%s != %s) {\n " %
(item_name, item_name))
+ if 'gl_version_flag' in item:
+ item_name = item['gl_version_flag']
+ inverted = ''
+ if item_name[0] == '!':
+ inverted = '!'
+ item_name = item_name[1:]
+ file.Write(" if (%sfeature_info_->gl_version_info().%s) {\n" %
+ (inverted, item_name))
file.Write(" gl%s(%s, %s);\n" %
(state['func'],
(item['enum_set']
if 'enum_set' in item else item['enum']),
item['name']))
+ if 'gl_version_flag' in item:
+ file.Write(" }\n")
if test_prev:
if 'extension_flag' in item:
file.Write(" ")
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc
index dcc7e18..6d8562f 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc
@@ -17,6 +17,7 @@ AsyncPixelTransferManager* AsyncPixelTransferManager::Create(
switch (gfx::GetGLImplementation()) {
case gfx::kGLImplementationOSMesaGL:
case gfx::kGLImplementationDesktopGL:
+ case gfx::kGLImplementationDesktopGLCoreProfile:
case gfx::kGLImplementationAppleGL:
return new AsyncPixelTransferManagerIdle(true);
case gfx::kGLImplementationMockGL:
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index d918526..17871b9 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -97,7 +97,8 @@ bool ContextGroup::Initialize(
GL_MAX_RENDERBUFFER_SIZE, kMinRenderbufferSize,
&max_renderbuffer_size)) {
LOG(ERROR) << "ContextGroup::Initialize failed because maximum "
- << "renderbuffer size too small.";
+ << "renderbuffer size too small (" << max_renderbuffer_size
+ << ", should be " << kMinRenderbufferSize << ").";
return false;
}
GLint max_samples = 0;
@@ -121,15 +122,13 @@ bool ContextGroup::Initialize(
draw_buffer_ = GL_BACK;
}
- const bool depth24_supported = feature_info_->feature_flags().oes_depth24;
-
buffer_manager_.reset(
new BufferManager(memory_tracker_.get(), feature_info_.get()));
framebuffer_manager_.reset(
new FramebufferManager(max_draw_buffers_, max_color_attachments_));
renderbuffer_manager_.reset(new RenderbufferManager(
memory_tracker_.get(), max_renderbuffer_size, max_samples,
- depth24_supported));
+ feature_info_.get()));
shader_manager_.reset(new ShaderManager());
valuebuffer_manager_.reset(
new ValuebufferManager(subscription_ref_set_.get(),
@@ -213,7 +212,7 @@ bool ContextGroup::Initialize(
return false;
}
- if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
+ if (feature_info_->gl_version_info().BehavesLikeGLES()) {
GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
&max_fragment_uniform_vectors_);
GetIntegerv(GL_MAX_VARYING_VECTORS, &max_varying_vectors_);
diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h
index 467f1ce..e6c63a6 100644
--- a/gpu/command_buffer/service/context_state_impl_autogen.h
+++ b/gpu/command_buffer/service/context_state_impl_autogen.h
@@ -242,7 +242,9 @@ void ContextState::InitState(const ContextState* prev_state) const {
if ((front_face != prev_state->front_face))
glFrontFace(front_face);
if (prev_state->hint_generate_mipmap != hint_generate_mipmap) {
- glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
+ if (!feature_info_->gl_version_info().is_desktop_core_profile) {
+ glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
+ }
}
if (feature_info_->feature_flags().oes_standard_derivatives) {
if (prev_state->hint_fragment_shader_derivative !=
@@ -330,7 +332,9 @@ void ContextState::InitState(const ContextState* prev_state) const {
glDepthMask(cached_depth_mask);
glDepthRange(z_near, z_far);
glFrontFace(front_face);
- glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
+ if (!feature_info_->gl_version_info().is_desktop_core_profile) {
+ glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
+ }
if (feature_info_->feature_flags().oes_standard_derivatives) {
glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES,
hint_fragment_shader_derivative);
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 6675ba7..0ff5be1 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -44,6 +44,10 @@ class StringSet {
Init(str);
}
+ StringSet(const std::vector<std::string>& strs) {
+ string_set_.insert(strs.begin(), strs.end());
+ }
+
void Init(const char* s) {
std::string str(s ? s : "");
Init(str);
@@ -63,6 +67,10 @@ class StringSet {
return string_set_.find(s) != string_set_.end();
}
+ const std::set<std::string>& GetImpl() {
+ return string_set_;
+ }
+
private:
std::set<std::string> string_set_;
};
@@ -272,15 +280,35 @@ bool IsGL_REDSupportedOnFBOs() {
void FeatureInfo::InitializeFeatures() {
// Figure out what extensions to turn on.
- StringSet extensions(
- reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
+ StringSet extensions;
+ // We need to figure out how to query the extension string before we
+ // have a GLVersionInfo available.
+ const char* version_str =
+ reinterpret_cast<const char*>(glGetString(GL_VERSION));
+ unsigned major_version, minor_version;
+ bool is_es, is_es3;
+ gfx::GLVersionInfo::ParseVersionString(
+ version_str, &major_version, &minor_version, &is_es, &is_es3);
+ if (!is_es && major_version >= 3) {
+ std::vector<std::string> exts;
+ GLint num_extensions = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+ for (GLint i = 0; i < num_extensions; ++i) {
+ const char* extension = reinterpret_cast<const char*>(
+ glGetStringi(GL_EXTENSIONS, i));
+ DCHECK(extension != NULL);
+ exts.push_back(extension);
+ }
+ extensions = exts;
+ } else {
+ extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ }
const char* renderer_str =
reinterpret_cast<const char*>(glGetString(GL_RENDERER));
- const char* version_str =
- reinterpret_cast<const char*>(glGetString(GL_VERSION));
- gl_version_info_.reset(new gfx::GLVersionInfo(version_str, renderer_str));
+ gl_version_info_.reset(new gfx::GLVersionInfo(
+ version_str, renderer_str, extensions.GetImpl()));
AddExtensionString("GL_ANGLE_translated_shader_source");
AddExtensionString("GL_CHROMIUM_async_pixel_transfers");
@@ -402,7 +430,8 @@ void FeatureInfo::InitializeFeatures() {
(extensions.Contains("GL_ARB_depth_texture") ||
extensions.Contains("GL_OES_depth_texture") ||
extensions.Contains("GL_ANGLE_depth_texture") ||
- gl_version_info_->is_es3)) {
+ gl_version_info_->is_es3 ||
+ gl_version_info_->is_desktop_core_profile)) {
enable_depth_texture = true;
feature_flags_.angle_depth_texture =
extensions.Contains("GL_ANGLE_depth_texture");
@@ -421,7 +450,8 @@ void FeatureInfo::InitializeFeatures() {
if (extensions.Contains("GL_EXT_packed_depth_stencil") ||
extensions.Contains("GL_OES_packed_depth_stencil") ||
- gl_version_info_->is_es3) {
+ gl_version_info_->is_es3 ||
+ gl_version_info_->is_desktop_core_profile) {
AddExtensionString("GL_OES_packed_depth_stencil");
feature_flags_.packed_depth24_stencil8 = true;
if (enable_depth_texture) {
@@ -435,6 +465,7 @@ void FeatureInfo::InitializeFeatures() {
}
if (gl_version_info_->is_es3 ||
+ gl_version_info_->is_desktop_core_profile ||
extensions.Contains("GL_OES_vertex_array_object") ||
extensions.Contains("GL_ARB_vertex_array_object") ||
extensions.Contains("GL_APPLE_vertex_array_object")) {
@@ -526,6 +557,7 @@ void FeatureInfo::InitializeFeatures() {
// Check if we should allow GL_OES_texture_npot
if (gl_version_info_->is_es3 ||
+ gl_version_info_->is_desktop_core_profile ||
extensions.Contains("GL_ARB_texture_non_power_of_two") ||
extensions.Contains("GL_OES_texture_npot")) {
AddExtensionString("GL_OES_texture_npot");
@@ -541,7 +573,8 @@ void FeatureInfo::InitializeFeatures() {
bool may_enable_chromium_color_buffer_float = false;
- if (extensions.Contains("GL_ARB_texture_float")) {
+ if (extensions.Contains("GL_ARB_texture_float") ||
+ gl_version_info_->is_desktop_core_profile) {
enable_texture_float = true;
enable_texture_float_linear = true;
enable_texture_half_float = true;
@@ -663,12 +696,14 @@ void FeatureInfo::InitializeFeatures() {
if (!workarounds_.disable_multisampling) {
bool ext_has_multisample =
extensions.Contains("GL_EXT_framebuffer_multisample") ||
- gl_version_info_->is_es3;
+ gl_version_info_->is_es3 ||
+ gl_version_info_->is_desktop_core_profile;
if (gl_version_info_->is_angle) {
ext_has_multisample |=
extensions.Contains("GL_ANGLE_framebuffer_multisample");
}
- feature_flags_.use_core_framebuffer_multisample = gl_version_info_->is_es3;
+ feature_flags_.use_core_framebuffer_multisample =
+ gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile;
if (ext_has_multisample) {
feature_flags_.chromium_framebuffer_multisample = true;
validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT);
@@ -753,7 +788,8 @@ void FeatureInfo::InitializeFeatures() {
// applications to start using it; they should use ordinary non-
// power-of-two textures. However, for unit testing purposes we
// expose it on all supported platforms.
- if (extensions.Contains("GL_ARB_texture_rectangle")) {
+ if (extensions.Contains("GL_ARB_texture_rectangle") ||
+ gl_version_info_->is_desktop_core_profile) {
AddExtensionString("GL_ARB_texture_rectangle");
feature_flags_.arb_texture_rectangle = true;
validators_.texture_bind_target.AddValue(GL_TEXTURE_RECTANGLE_ARB);
@@ -803,7 +839,8 @@ void FeatureInfo::InitializeFeatures() {
!enable_texture_format_bgra8888);
if (extensions.Contains("GL_EXT_texture_storage") ||
extensions.Contains("GL_ARB_texture_storage") ||
- support_texture_storage_on_es3) {
+ support_texture_storage_on_es3 ||
+ gl_version_info_->is_desktop_core_profile) {
feature_flags_.ext_texture_storage = true;
AddExtensionString("GL_EXT_texture_storage");
validators_.texture_parameter.AddValue(GL_TEXTURE_IMMUTABLE_FORMAT_EXT);
@@ -865,7 +902,8 @@ void FeatureInfo::InitializeFeatures() {
if (!workarounds_.disable_ext_draw_buffers &&
(vendor_agnostic_draw_buffers ||
(extensions.Contains("GL_NV_draw_buffers") &&
- gl_version_info_->is_es3))) {
+ gl_version_info_->is_es3) ||
+ gl_version_info_->is_desktop_core_profile)) {
AddExtensionString("GL_EXT_draw_buffers");
feature_flags_.ext_draw_buffers = true;
@@ -937,6 +975,7 @@ void FeatureInfo::InitializeFeatures() {
feature_flags_.map_buffer_range =
gl_version_info_->is_es3 ||
+ gl_version_info_->is_desktop_core_profile ||
extensions.Contains("GL_ARB_map_buffer_range") ||
extensions.Contains("GL_EXT_map_buffer_range");
@@ -944,6 +983,7 @@ void FeatureInfo::InitializeFeatures() {
// extension is still advertised.
bool has_pixel_buffers =
gl_version_info_->is_es3 ||
+ gl_version_info_->is_desktop_core_profile ||
extensions.Contains("GL_ARB_pixel_buffer_object") ||
extensions.Contains("GL_NV_pixel_buffer_object");
@@ -1017,7 +1057,8 @@ void FeatureInfo::InitializeFeatures() {
}
}
- if ((gl_version_info_->is_es3 || extensions.Contains("GL_EXT_texture_rg") ||
+ if ((gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile ||
+ extensions.Contains("GL_EXT_texture_rg") ||
extensions.Contains("GL_ARB_texture_rg")) &&
IsGL_REDSupportedOnFBOs()) {
feature_flags_.ext_texture_rg = true;
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index 177ef10..f4b2dac 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -42,7 +42,13 @@ class FeatureInfoTest : public GpuServiceTest {
}
void SetupInitExpectations(const char* extensions) {
- SetupInitExpectationsWithGLVersion(extensions, "", "3.0");
+ std::string extensions_str = extensions;
+ // Most of the tests' expectations currently assume the desktop
+ // OpenGL compatibility profile.
+ if (extensions_str.find("GL_ARB_compatibility") == std::string::npos) {
+ extensions_str += " GL_ARB_compatibility";
+ }
+ SetupInitExpectationsWithGLVersion(extensions_str.c_str(), "", "3.0");
}
void SetupInitExpectationsWithGLVersion(
@@ -1382,7 +1388,8 @@ TEST_F(FeatureInfoTest, ARBSyncDisabled) {
TEST_F(FeatureInfoTest, InitializeCHROMIUM_path_rendering) {
SetupInitExpectationsWithGLVersion(
- "GL_NV_path_rendering GL_EXT_direct_state_access", "", "4.3");
+ "GL_ARB_compatibility GL_NV_path_rendering GL_EXT_direct_state_access",
+ "", "4.3");
EXPECT_TRUE(info_->feature_flags().chromium_path_rendering);
EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering"));
}
@@ -1395,21 +1402,22 @@ TEST_F(FeatureInfoTest, InitializeCHROMIUM_path_rendering2) {
}
TEST_F(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering) {
- SetupInitExpectationsWithGLVersion("", "", "4.3");
+ SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3");
EXPECT_FALSE(info_->feature_flags().chromium_path_rendering);
EXPECT_THAT(info_->extensions(),
Not(HasSubstr("GL_CHROMIUM_path_rendering")));
}
TEST_F(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering2) {
- SetupInitExpectationsWithGLVersion("GL_NV_path_rendering", "", "4.3");
+ SetupInitExpectationsWithGLVersion(
+ "GL_ARB_compatibility GL_NV_path_rendering", "", "4.3");
EXPECT_FALSE(info_->feature_flags().chromium_path_rendering);
EXPECT_THAT(info_->extensions(),
Not(HasSubstr("GL_CHROMIUM_path_rendering")));
}
TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced) {
- SetupInitExpectationsWithGLVersion("", "", "4.3");
+ SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3");
EXPECT_FALSE(info_->feature_flags().blend_equation_advanced);
EXPECT_THAT(info_->extensions(),
Not(HasSubstr("GL_KHR_blend_equation_advanced")));
@@ -1428,7 +1436,7 @@ TEST_F(FeatureInfoTest, InitializeNV_blend_equations_advanced) {
}
TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced_coherent) {
- SetupInitExpectationsWithGLVersion("", "", "4.3");
+ SetupInitExpectationsWithGLVersion("GL_ARB_compatibility ", "", "4.3");
EXPECT_FALSE(info_->feature_flags().blend_equation_advanced_coherent);
EXPECT_THAT(info_->extensions(),
Not(HasSubstr("GL_KHR_blend_equation_advanced_coherent")));
diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
index ddd3739..66fb260 100644
--- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
@@ -26,7 +26,6 @@ const GLint kMaxRenderbufferSize = 64;
const GLint kMaxSamples = 4;
const uint32 kMaxDrawBuffers = 16;
const uint32 kMaxColorAttachments = 16;
-const bool kDepth24Supported = false;
const bool kUseDefaultTextures = false;
} // namespace
@@ -35,27 +34,30 @@ class FramebufferManagerTest : public GpuServiceTest {
public:
FramebufferManagerTest()
: manager_(1, 1),
- texture_manager_(NULL,
- new FeatureInfo(),
- kMaxTextureSize,
- kMaxCubemapSize,
- kMaxRectangleTextureSize,
- kUseDefaultTextures),
- renderbuffer_manager_(NULL,
- kMaxRenderbufferSize,
- kMaxSamples,
- kDepth24Supported) {}
+ feature_info_(new FeatureInfo()) {
+ texture_manager_.reset(new TextureManager(NULL,
+ feature_info_.get(),
+ kMaxTextureSize,
+ kMaxCubemapSize,
+ kMaxRectangleTextureSize,
+ kUseDefaultTextures));
+ renderbuffer_manager_.reset(new RenderbufferManager(NULL,
+ kMaxRenderbufferSize,
+ kMaxSamples,
+ feature_info_.get()));
+ }
~FramebufferManagerTest() override {
manager_.Destroy(false);
- texture_manager_.Destroy(false);
- renderbuffer_manager_.Destroy(false);
+ texture_manager_->Destroy(false);
+ renderbuffer_manager_->Destroy(false);
}
protected:
FramebufferManager manager_;
- TextureManager texture_manager_;
- RenderbufferManager renderbuffer_manager_;
+ scoped_refptr<FeatureInfo> feature_info_;
+ scoped_ptr<TextureManager> texture_manager_;
+ scoped_ptr<RenderbufferManager> renderbuffer_manager_;
};
TEST_F(FramebufferManagerTest, Basic) {
@@ -109,20 +111,22 @@ class FramebufferInfoTest : public GpuServiceTest {
FramebufferInfoTest()
: manager_(kMaxDrawBuffers, kMaxColorAttachments),
- feature_info_(new FeatureInfo()),
- renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
- kDepth24Supported) {
+ feature_info_(new FeatureInfo()) {
texture_manager_.reset(new TextureManager(NULL,
feature_info_.get(),
kMaxTextureSize,
kMaxCubemapSize,
kMaxRectangleTextureSize,
kUseDefaultTextures));
+ renderbuffer_manager_.reset(new RenderbufferManager(NULL,
+ kMaxRenderbufferSize,
+ kMaxSamples,
+ feature_info_.get()));
}
~FramebufferInfoTest() override {
manager_.Destroy(false);
texture_manager_->Destroy(false);
- renderbuffer_manager_.Destroy(false);
+ renderbuffer_manager_->Destroy(false);
}
protected:
@@ -145,7 +149,7 @@ class FramebufferInfoTest : public GpuServiceTest {
Framebuffer* framebuffer_;
scoped_refptr<FeatureInfo> feature_info_;
scoped_ptr<TextureManager> texture_manager_;
- RenderbufferManager renderbuffer_manager_;
+ scoped_ptr<RenderbufferManager> renderbuffer_manager_;
scoped_ptr<MockErrorState> error_state_;
};
@@ -205,10 +209,10 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
EXPECT_FALSE(
framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient1Id, kRenderbufferService1Id);
Renderbuffer* renderbuffer1 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id);
ASSERT_TRUE(renderbuffer1 != NULL);
// check adding one attachment
@@ -224,13 +228,13 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
EXPECT_TRUE(framebuffer_->IsCleared());
// Try a format that's not good for COLOR_ATTACHMENT0.
- renderbuffer_manager_.SetInfo(
+ renderbuffer_manager_->SetInfo(
renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1);
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
// Try a good format.
- renderbuffer_manager_.SetInfo(
+ renderbuffer_manager_->SetInfo(
renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
EXPECT_EQ(static_cast<GLenum>(kFormat1),
framebuffer_->GetColorAttachmentFormat());
@@ -241,10 +245,10 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
EXPECT_FALSE(framebuffer_->IsCleared());
// check adding another
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient2Id, kRenderbufferService2Id);
Renderbuffer* renderbuffer2 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient2Id);
ASSERT_TRUE(renderbuffer2 != NULL);
framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2);
EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
@@ -263,7 +267,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
EXPECT_FALSE(framebuffer_->IsCleared());
- renderbuffer_manager_.SetInfo(
+ renderbuffer_manager_->SetInfo(
renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2);
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
@@ -272,7 +276,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
// check marking them as cleared.
manager_.MarkAttachmentsAsCleared(
- framebuffer_, &renderbuffer_manager_, texture_manager_.get());
+ framebuffer_, renderbuffer_manager_.get(), texture_manager_.get());
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
@@ -280,14 +284,14 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
EXPECT_TRUE(framebuffer_->IsCleared());
// Check adding one that is already cleared.
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient3Id, kRenderbufferService3Id);
Renderbuffer* renderbuffer3 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient3Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient3Id);
ASSERT_TRUE(renderbuffer3 != NULL);
- renderbuffer_manager_.SetInfo(
+ renderbuffer_manager_->SetInfo(
renderbuffer3, kSamples3, kFormat3, kWidth3, kHeight3);
- renderbuffer_manager_.SetCleared(renderbuffer3, true);
+ renderbuffer_manager_->SetCleared(renderbuffer3, true);
framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer3);
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
@@ -300,7 +304,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
EXPECT_TRUE(framebuffer_->IsCleared());
// Check marking the renderbuffer as unclared.
- renderbuffer_manager_.SetInfo(
+ renderbuffer_manager_->SetInfo(
renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
EXPECT_EQ(static_cast<GLenum>(kFormat1),
framebuffer_->GetColorAttachmentFormat());
@@ -323,17 +327,17 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
// Clear it.
manager_.MarkAttachmentsAsCleared(
- framebuffer_, &renderbuffer_manager_, texture_manager_.get());
+ framebuffer_, renderbuffer_manager_.get(), texture_manager_.get());
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_TRUE(framebuffer_->IsCleared());
// Check replacing an attachment
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient4Id, kRenderbufferService4Id);
Renderbuffer* renderbuffer4 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient4Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient4Id);
ASSERT_TRUE(renderbuffer4 != NULL);
- renderbuffer_manager_.SetInfo(
+ renderbuffer_manager_->SetInfo(
renderbuffer4, kSamples4, kFormat4, kWidth4, kHeight4);
framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4);
@@ -351,7 +355,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
framebuffer_->IsPossiblyComplete());
// Check changing an attachment.
- renderbuffer_manager_.SetInfo(
+ renderbuffer_manager_->SetInfo(
renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4);
attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT);
@@ -379,7 +383,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
// Remove depth, Set color to 0 size.
framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, NULL);
- renderbuffer_manager_.SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0);
+ renderbuffer_manager_->SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0);
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
@@ -735,15 +739,15 @@ TEST_F(FramebufferInfoTest, UnbindRenderbuffer) {
const GLuint kRenderbufferClient2Id = 34;
const GLuint kRenderbufferService2Id = 334;
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient1Id, kRenderbufferService1Id);
Renderbuffer* renderbuffer1 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id);
ASSERT_TRUE(renderbuffer1 != NULL);
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient2Id, kRenderbufferService2Id);
Renderbuffer* renderbuffer2 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient2Id);
ASSERT_TRUE(renderbuffer2 != NULL);
// Attach to 2 attachment points.
@@ -811,10 +815,10 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
const GLint kLevel1 = 0;
const GLint kSamples1 = 0;
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient1Id, kRenderbufferService1Id);
Renderbuffer* renderbuffer1 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id);
ASSERT_TRUE(renderbuffer1 != NULL);
texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
scoped_refptr<TextureRef> texture2(
@@ -836,7 +840,7 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
// Check MarkAttachmentsAsCleared marks as complete.
manager_.MarkAttachmentsAsCleared(
- framebuffer_, &renderbuffer_manager_, texture_manager_.get());
+ framebuffer_, renderbuffer_manager_.get(), texture_manager_.get());
EXPECT_TRUE(manager_.IsComplete(framebuffer_));
// Check Unbind marks as not complete.
@@ -857,10 +861,10 @@ TEST_F(FramebufferInfoTest, GetStatus) {
const GLint kLevel1 = 0;
const GLint kSamples1 = 0;
- renderbuffer_manager_.CreateRenderbuffer(
+ renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient1Id, kRenderbufferService1Id);
Renderbuffer* renderbuffer1 =
- renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
+ renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id);
ASSERT_TRUE(renderbuffer1 != NULL);
texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
scoped_refptr<TextureRef> texture2(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 3abe199..d402c93 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2733,17 +2733,39 @@ bool GLES2DecoderImpl::Initialize(
// can't do anything about that.
if (!surfaceless_) {
- GLint v = 0;
- glGetIntegerv(GL_ALPHA_BITS, &v);
+ GLint alpha_bits = 0;
+ GLint depth_bits = 0;
+ GLint stencil_bits = 0;
+
+ bool default_fb = (GetBackbufferServiceId() == 0);
+
+ if (feature_info_->gl_version_info().is_desktop_core_profile) {
+ glGetFramebufferAttachmentParameterivEXT(
+ GL_FRAMEBUFFER,
+ default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
+ glGetFramebufferAttachmentParameterivEXT(
+ GL_FRAMEBUFFER,
+ default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits);
+ glGetFramebufferAttachmentParameterivEXT(
+ GL_FRAMEBUFFER,
+ default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits);
+ } else {
+ glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
+ glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
+ glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
+ }
+
// This checks if the user requested RGBA and we have RGBA then RGBA. If
// the user requested RGB then RGB. If the user did not specify a
// preference than use whatever we were given. Same for DEPTH and STENCIL.
back_buffer_color_format_ =
- (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
- glGetIntegerv(GL_DEPTH_BITS, &v);
- back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
- glGetIntegerv(GL_STENCIL_BITS, &v);
- back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
+ (attrib_parser.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB;
+ back_buffer_has_depth_ = attrib_parser.depth_size != 0 && depth_bits > 0;
+ back_buffer_has_stencil_ =
+ attrib_parser.stencil_size != 0 && stencil_bits > 0;
}
state_.viewport_width = surface->GetSize().width();
@@ -2756,7 +2778,7 @@ bool GLES2DecoderImpl::Initialize(
// mailing list archives. It also implicitly enables the desktop GL
// capability GL_POINT_SPRITE to provide access to the gl_PointCoord
// variable in fragment shaders.
- if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
+ if (!feature_info_->gl_version_info().BehavesLikeGLES()) {
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_POINT_SPRITE);
}
@@ -4749,23 +4771,93 @@ bool GLES2DecoderImpl::GetHelper(
*num_written = 1;
if (params) {
GLint v = 0;
- glGetIntegerv(GL_ALPHA_BITS, &v);
- params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
+ if (feature_info_->gl_version_info().is_desktop_core_profile) {
+ Framebuffer* framebuffer =
+ GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
+ if (framebuffer) {
+ glGetFramebufferAttachmentParameterivEXT(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v);
+ } else {
+ v = (back_buffer_color_format_ == GL_RGBA ? 8 : 0);
+ }
+ } else {
+ glGetIntegerv(GL_ALPHA_BITS, &v);
+ }
+ params[0] =
+ BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
}
return true;
case GL_DEPTH_BITS:
*num_written = 1;
if (params) {
GLint v = 0;
- glGetIntegerv(GL_DEPTH_BITS, &v);
+ if (feature_info_->gl_version_info().is_desktop_core_profile) {
+ Framebuffer* framebuffer =
+ GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
+ if (framebuffer) {
+ glGetFramebufferAttachmentParameterivEXT(
+ GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v);
+ } else {
+ v = (back_buffer_has_depth_ ? 24 : 0);
+ }
+ } else {
+ glGetIntegerv(GL_DEPTH_BITS, &v);
+ }
params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
}
return true;
+ case GL_RED_BITS:
+ case GL_GREEN_BITS:
+ case GL_BLUE_BITS:
+ *num_written = 1;
+ if (params) {
+ GLint v = 0;
+ if (feature_info_->gl_version_info().is_desktop_core_profile) {
+ Framebuffer* framebuffer =
+ GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
+ if (framebuffer) {
+ GLenum framebuffer_enum = 0;
+ switch (pname) {
+ case GL_RED_BITS:
+ framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
+ break;
+ case GL_GREEN_BITS:
+ framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
+ break;
+ case GL_BLUE_BITS:
+ framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
+ break;
+ }
+ glGetFramebufferAttachmentParameterivEXT(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, framebuffer_enum, &v);
+ } else {
+ v = 8;
+ }
+ } else {
+ glGetIntegerv(pname, &v);
+ }
+ params[0] = v;
+ }
+ return true;
case GL_STENCIL_BITS:
*num_written = 1;
if (params) {
GLint v = 0;
- glGetIntegerv(GL_STENCIL_BITS, &v);
+ if (feature_info_->gl_version_info().is_desktop_core_profile) {
+ Framebuffer* framebuffer =
+ GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
+ if (framebuffer) {
+ glGetFramebufferAttachmentParameterivEXT(
+ GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v);
+ } else {
+ v = (back_buffer_has_stencil_ ? 8 : 0);
+ }
+ } else {
+ glGetIntegerv(GL_STENCIL_BITS, &v);
+ }
params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
}
return true;
@@ -6612,7 +6704,7 @@ bool GLES2DecoderImpl::SimulateAttrib0(
DCHECK(simulated);
*simulated = false;
- if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
+ if (feature_info_->gl_version_info().BehavesLikeGLES())
return true;
const VertexAttrib* attrib =
@@ -8358,7 +8450,8 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
return error::kNoError;
}
- const char* str = reinterpret_cast<const char*>(glGetString(name));
+
+ const char* str = nullptr;
std::string extensions;
switch (name) {
case GL_VERSION:
@@ -8373,6 +8466,8 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
// They are used by WEBGL_debug_renderer_info.
if (!force_webgl_glsl_validation_)
str = "Chromium";
+ else
+ str = reinterpret_cast<const char*>(glGetString(name));
break;
case GL_EXTENSIONS:
{
@@ -8418,6 +8513,7 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
}
break;
default:
+ str = reinterpret_cast<const char*>(glGetString(name));
break;
}
Bucket* bucket = CreateBucket(c.bucket_id);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 119096bb..8648134 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -126,6 +126,7 @@ void GLES2DecoderTestBase::SetUp() {
// Autogenerated tests do not overwrite version or extension string,
// so we have to pick something that supports everything here.
init.gl_version = "4.4";
+ init.extensions += " GL_ARB_compatibility";
init.has_alpha = true;
init.has_depth = true;
init.request_alpha = true;
@@ -321,13 +322,15 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine(
.WillOnce(SetArgumentPointee<1>(normalized_init.has_stencil ? 8 : 0))
.RetiresOnSaturation();
- EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE))
- .Times(1)
- .RetiresOnSaturation();
+ if (!group_->feature_info()->gl_version_info().BehavesLikeGLES()) {
+ EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE))
+ .Times(1)
+ .RetiresOnSaturation();
- EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE))
- .Times(1)
- .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
static GLint max_viewport_dims[] = {
kMaxViewportWidth,
@@ -1684,7 +1687,7 @@ void GLES2DecoderTestBase::DeleteIndexBuffer() {
void GLES2DecoderTestBase::AddExpectationsForSimulatedAttrib0WithError(
GLsizei num_vertices, GLuint buffer_id, GLenum error) {
- if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
+ if (group_->feature_info()->gl_version_info().BehavesLikeGLES()) {
return;
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc
index 957b53b..fc5e2de 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc
@@ -60,7 +60,10 @@ class GLES2DecoderGeometryInstancingTest : public GLES2DecoderWithShaderTest {
void SetUp() override {
InitState init;
init.extensions = "GL_ANGLE_instanced_arrays";
- init.gl_version = "opengl es 2.0";
+ // Most of the tests in this file assume they're running on
+ // desktop OpenGL, and large portions of the tests will become
+ // no-ops if they aren't.
+ init.gl_version = "opengl 2.1";
init.has_alpha = true;
init.has_depth = true;
init.request_alpha = true;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
index 21526b1..4255ffa 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -1543,7 +1543,7 @@ class GLES2DecoderMultisampledRenderToTextureTest
*gl_,
RenderbufferStorageMultisampleIMG(GL_RENDERBUFFER,
TestHelper::kMaxSamples,
- GL_RGBA,
+ GL_RGBA4,
TestHelper::kMaxRenderbufferSize,
1))
.Times(1)
@@ -1553,7 +1553,7 @@ class GLES2DecoderMultisampledRenderToTextureTest
*gl_,
RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
TestHelper::kMaxSamples,
- GL_RGBA,
+ GL_RGBA4,
TestHelper::kMaxRenderbufferSize,
1))
.Times(1)
diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc
index 4b4337e..2af22de 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.cc
+++ b/gpu/command_buffer/service/renderbuffer_manager.cc
@@ -8,6 +8,7 @@
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "ui/gl/gl_implementation.h"
@@ -43,12 +44,12 @@ RenderbufferManager::RenderbufferManager(
MemoryTracker* memory_tracker,
GLint max_renderbuffer_size,
GLint max_samples,
- bool depth24_supported)
+ FeatureInfo* feature_info)
: memory_tracker_(
new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
max_renderbuffer_size_(max_renderbuffer_size),
max_samples_(max_samples),
- depth24_supported_(depth24_supported),
+ feature_info_(feature_info),
num_uncleared_renderbuffers_(0),
renderbuffer_count_(0),
have_context_(true) {
@@ -210,7 +211,7 @@ bool RenderbufferManager::ComputeEstimatedRenderbufferSize(int width,
GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat(
GLenum impl_format) const {
- if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
+ if (!feature_info_->gl_version_info().BehavesLikeGLES()) {
switch (impl_format) {
case GL_DEPTH_COMPONENT16:
return GL_DEPTH_COMPONENT;
@@ -222,7 +223,8 @@ GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat(
}
} else {
// Upgrade 16-bit depth to 24-bit if possible.
- if (impl_format == GL_DEPTH_COMPONENT16 && depth24_supported_)
+ if (impl_format == GL_DEPTH_COMPONENT16 &&
+ feature_info_->feature_flags().oes_depth24)
return GL_DEPTH_COMPONENT24;
}
return impl_format;
diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h
index 71f830a..be4cc09 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.h
+++ b/gpu/command_buffer/service/renderbuffer_manager.h
@@ -17,6 +17,7 @@
namespace gpu {
namespace gles2 {
+class FeatureInfo;
class RenderbufferManager;
// Info about a Renderbuffer.
@@ -128,7 +129,7 @@ class GPU_EXPORT RenderbufferManager {
RenderbufferManager(MemoryTracker* memory_tracker,
GLint max_renderbuffer_size,
GLint max_samples,
- bool depth24_supported);
+ FeatureInfo* feature_info);
~RenderbufferManager();
GLint max_renderbuffer_size() const {
@@ -182,7 +183,8 @@ class GPU_EXPORT RenderbufferManager {
GLint max_renderbuffer_size_;
GLint max_samples_;
- bool depth24_supported_;
+
+ scoped_refptr<FeatureInfo> feature_info_;
int num_uncleared_renderbuffers_;
diff --git a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc
index 7c625e6..7633f68 100644
--- a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc
@@ -6,8 +6,10 @@
#include <set>
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
@@ -23,10 +25,19 @@ class RenderbufferManagerTestBase : public GpuServiceTest {
static const GLint kMaxSamples = 4;
protected:
- void SetUpBase(MemoryTracker* memory_tracker, bool depth24_supported) {
+ void SetUpBase(MemoryTracker* memory_tracker,
+ bool depth24_supported,
+ bool use_gles) {
GpuServiceTest::SetUp();
+ feature_info_ = new FeatureInfo();
+ TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
+ gl_.get(),
+ depth24_supported ? "GL_OES_depth24" : "",
+ "",
+ use_gles ? "OpenGL ES 2.0" : "OpenGL 2.1");
+ feature_info_->Initialize();
manager_.reset(new RenderbufferManager(
- memory_tracker, kMaxSize, kMaxSamples, depth24_supported));
+ memory_tracker, kMaxSize, kMaxSamples, feature_info_.get()));
}
void TearDown() override {
@@ -35,6 +46,7 @@ class RenderbufferManagerTestBase : public GpuServiceTest {
GpuServiceTest::TearDown();
}
+ scoped_refptr<FeatureInfo> feature_info_;
scoped_ptr<RenderbufferManager> manager_;
};
@@ -42,7 +54,8 @@ class RenderbufferManagerTest : public RenderbufferManagerTestBase {
protected:
void SetUp() override {
bool depth24_supported = false;
- SetUpBase(NULL, depth24_supported);
+ bool use_gles = false;
+ SetUpBase(NULL, depth24_supported, use_gles);
}
};
@@ -52,7 +65,8 @@ class RenderbufferManagerMemoryTrackerTest
void SetUp() override {
mock_memory_tracker_ = new StrictMock<MockMemoryTracker>();
bool depth24_supported = false;
- SetUpBase(mock_memory_tracker_.get(), depth24_supported);
+ bool use_gles = false;
+ SetUpBase(mock_memory_tracker_.get(), depth24_supported, use_gles);
}
scoped_refptr<MockMemoryTracker> mock_memory_tracker_;
@@ -291,29 +305,34 @@ TEST_F(RenderbufferManagerTest, AddToSignature) {
.RetiresOnSaturation();
}
-class RenderbufferManagerFormatTest : public RenderbufferManagerTestBase {
+class RenderbufferManagerFormatGLESTest : public RenderbufferManagerTestBase {
protected:
void SetUp() override {
bool depth24_supported = true;
- SetUpBase(NULL, depth24_supported);
+ bool use_gles = true;
+ SetUpBase(NULL, depth24_supported, use_gles);
}
};
-TEST_F(RenderbufferManagerFormatTest, UpgradeDepthFormatOnGLES) {
- gfx::GLImplementation prev_impl = gfx::GetGLImplementation();
- gfx::SetGLImplementation(gfx::kGLImplementationEGLGLES2);
+TEST_F(RenderbufferManagerFormatGLESTest, UpgradeDepthFormatOnGLES) {
GLenum impl_format =
manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16);
- gfx::SetGLImplementation(prev_impl);
EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT24), impl_format);
}
-TEST_F(RenderbufferManagerFormatTest, UseUnsizedDepthFormatOnNonGLES) {
- gfx::GLImplementation prev_impl = gfx::GetGLImplementation();
- gfx::SetGLImplementation(gfx::kGLImplementationDesktopGL);
+class RenderbufferManagerFormatNonGLESTest :
+ public RenderbufferManagerTestBase {
+ protected:
+ void SetUp() override {
+ bool depth24_supported = true;
+ bool use_gles = false;
+ SetUpBase(NULL, depth24_supported, use_gles);
+ }
+};
+
+TEST_F(RenderbufferManagerFormatNonGLESTest, UseUnsizedDepthFormatOnNonGLES) {
GLenum impl_format =
manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16);
- gfx::SetGLImplementation(prev_impl);
EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT), impl_format);
}
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc
index c0904c7b..b4a94fc 100644
--- a/gpu/command_buffer/service/shader_translator.cc
+++ b/gpu/command_buffer/service/shader_translator.cc
@@ -15,6 +15,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "ui/gl/gl_implementation.h"
namespace gpu {
namespace gles2 {
@@ -120,8 +121,15 @@ bool ShaderTranslator::Init(
if (glsl_implementation_type == kGlslES) {
shader_output = SH_ESSL_OUTPUT;
} else {
- shader_output = (shader_spec == SH_WEBGL2_SPEC) ? SH_GLSL_CORE_OUTPUT :
- SH_GLSL_COMPATIBILITY_OUTPUT;
+ // TODO(kbr): clean up the tests of shader_spec and
+ // gfx::GetGLImplementation(). crbug.com/471960
+ if (shader_spec == SH_WEBGL2_SPEC ||
+ gfx::GetGLImplementation() ==
+ gfx::kGLImplementationDesktopGLCoreProfile) {
+ shader_output = SH_GLSL_CORE_OUTPUT;
+ } else {
+ shader_output = SH_GLSL_COMPATIBILITY_OUTPUT;
+ }
}
{
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index 096a60c..2104ddb 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -18,6 +18,7 @@
#include "gpu/command_buffer/service/texture_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_version_info.h"
using ::testing::_;
using ::testing::DoAll;
@@ -80,6 +81,8 @@ const GLint TestHelper::kMaxVertexUniformVectors;
const GLint TestHelper::kMaxVertexUniformComponents;
#endif
+std::vector<std::string> TestHelper::split_extensions_;
+
void TestHelper::SetupTextureInitializationExpectations(
::gfx::MockGLInterface* gl,
GLenum target,
@@ -270,14 +273,14 @@ void TestHelper::SetupContextGroupInitExpectations(
SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version);
- std::string l_version(base::StringToLowerASCII(std::string(gl_version)));
- bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");
+ gfx::GLVersionInfo gl_info(gl_version, "", extensions);
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _))
.WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize))
.RetiresOnSaturation();
if (strstr(extensions, "GL_EXT_framebuffer_multisample") ||
- strstr(extensions, "GL_EXT_multisampled_render_to_texture") || is_es3) {
+ strstr(extensions, "GL_EXT_multisampled_render_to_texture") ||
+ gl_info.is_es3) {
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _))
.WillOnce(SetArgumentPointee<1>(kMaxSamples))
.RetiresOnSaturation();
@@ -309,15 +312,28 @@ void TestHelper::SetupContextGroupInitExpectations(
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _))
.WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits))
.RetiresOnSaturation();
- EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _))
- .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents))
- .RetiresOnSaturation();
- EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _))
- .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats))
- .RetiresOnSaturation();
- EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _))
- .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents))
- .RetiresOnSaturation();
+
+ if (gl_info.is_es) {
+ EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _))
+ .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_VECTORS, _))
+ .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, _))
+ .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors))
+ .RetiresOnSaturation();
+ } else {
+ EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _))
+ .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _))
+ .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _))
+ .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents))
+ .RetiresOnSaturation();
+ }
bool use_default_textures = bind_generates_resource;
SetupTextureManagerInitExpectations(gl, extensions, use_default_textures);
@@ -335,21 +351,39 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
const char* gl_version) {
InSequence sequence;
- EXPECT_CALL(*gl, GetString(GL_EXTENSIONS))
- .WillOnce(Return(reinterpret_cast<const uint8*>(extensions)))
- .RetiresOnSaturation();
- EXPECT_CALL(*gl, GetString(GL_RENDERER))
- .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer)))
- .RetiresOnSaturation();
EXPECT_CALL(*gl, GetString(GL_VERSION))
.WillOnce(Return(reinterpret_cast<const uint8*>(gl_version)))
.RetiresOnSaturation();
- std::string l_version(base::StringToLowerASCII(std::string(gl_version)));
- bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");
+ // Persistent storage is needed for the split extension string.
+ split_extensions_.clear();
+ if (extensions) {
+ Tokenize(extensions, " ", &split_extensions_);
+ }
+
+ gfx::GLVersionInfo gl_info(gl_version, gl_renderer, extensions);
+ if (!gl_info.is_es && gl_info.major_version >= 3) {
+ EXPECT_CALL(*gl, GetIntegerv(GL_NUM_EXTENSIONS, _))
+ .WillOnce(SetArgumentPointee<1>(split_extensions_.size()))
+ .RetiresOnSaturation();
+ for (size_t ii = 0; ii < split_extensions_.size(); ++ii) {
+ EXPECT_CALL(*gl, GetStringi(GL_EXTENSIONS, ii))
+ .WillOnce(Return(reinterpret_cast<const uint8*>(
+ split_extensions_[ii].c_str())))
+ .RetiresOnSaturation();
+ }
+ } else {
+ EXPECT_CALL(*gl, GetString(GL_EXTENSIONS))
+ .WillOnce(Return(reinterpret_cast<const uint8*>(extensions)))
+ .RetiresOnSaturation();
+ }
+
+ EXPECT_CALL(*gl, GetString(GL_RENDERER))
+ .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer)))
+ .RetiresOnSaturation();
if (strstr(extensions, "GL_ARB_texture_float") ||
- (is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) {
+ (gl_info.is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) {
static const GLuint tx_ids[] = {101, 102};
static const GLuint fb_ids[] = {103, 104};
const GLsizei width = 16;
@@ -390,7 +424,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
GL_RGB, GL_FLOAT, _))
.Times(1)
.RetiresOnSaturation();
- if (is_es3) {
+ if (gl_info.is_es3) {
EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
.WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
.RetiresOnSaturation();
@@ -420,7 +454,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
if (strstr(extensions, "GL_EXT_draw_buffers") ||
strstr(extensions, "GL_ARB_draw_buffers") ||
- (is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) {
+ (gl_info.is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) {
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _))
.WillOnce(SetArgumentPointee<1>(8))
.RetiresOnSaturation();
@@ -429,7 +463,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
.RetiresOnSaturation();
}
- if (is_es3 || strstr(extensions, "GL_EXT_texture_rg") ||
+ if (gl_info.is_es3 || strstr(extensions, "GL_EXT_texture_rg") ||
(strstr(extensions, "GL_ARB_texture_rg"))) {
static const GLuint tx_ids[] = {101, 102};
static const GLuint fb_ids[] = {103, 104};
diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h
index a536cce..2cf3f96 100644
--- a/gpu/command_buffer/service/test_helper.h
+++ b/gpu/command_buffer/service/test_helper.h
@@ -5,6 +5,9 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_
#define GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_
+#include <string>
+#include <vector>
+
#include "gpu/command_buffer/service/shader_translator.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
@@ -140,6 +143,8 @@ class TestHelper {
static void SetupTextureDestructionExpectations(::gfx::MockGLInterface* gl,
GLenum target,
bool use_default_textures);
+
+ static std::vector<std::string> split_extensions_;
};
// This object temporaritly Sets what gfx::GetGLImplementation returns. During
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index fdeb96c..9b5d9f5 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -25,6 +25,7 @@ UNCONDITIONALLY_BOUND_EXTENSIONS = set([
'WGL_ARB_extensions_string',
'WGL_EXT_extensions_string',
'GL_CHROMIUM_gles_depth_binding_hack', # crbug.com/448206
+ 'GL_CHROMIUM_glgetstringi_hack', # crbug.com/470396
])
"""Function binding conditions can be specified manually by supplying a versions
@@ -612,7 +613,10 @@ GL_FUNCTIONS = [
'names': ['glGetString'],
'arguments': 'GLenum name', },
{ 'return_type': 'const GLubyte*',
- 'names': ['glGetStringi'],
+ # This is needed for bootstrapping on the desktop GL core profile.
+ # It won't be called unless the expected GL version is used.
+ 'versions': [{ 'name': 'glGetStringi',
+ 'extensions': ['GL_CHROMIUM_glgetstringi_hack'] }],
'arguments': 'GLenum name, GLuint index', },
{ 'return_type': 'void',
'versions': [{ 'name': 'glGetSynciv',
@@ -1775,7 +1779,7 @@ def GenerateMockHeader(file, functions, set_name):
file.write('\n')
-def GenerateSource(file, functions, set_name, used_extensions):
+def GenerateSource(file, functions, set_name, used_extensions, options):
"""Generates gl_bindings_autogen_x.cc"""
set_header_name = "ui/gl/gl_" + set_name.lower() + "_api_implementation.h"
@@ -1971,6 +1975,11 @@ namespace gfx {
(set_name.lower(), function_name, argument_names))
if 'logging_code' in func:
file.write("%s\n" % func['logging_code'])
+ if options.generate_dchecks and set_name == 'gl':
+ file.write(' {\n')
+ file.write(' GLenum error = g_driver_gl.debug_fn.glGetErrorFn();\n')
+ file.write(' DCHECK(error == 0);\n')
+ file.write(' }\n')
else:
file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
(function_name, log_argument_names))
@@ -1980,6 +1989,11 @@ namespace gfx {
file.write("%s\n" % func['logging_code'])
else:
file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n')
+ if options.generate_dchecks and set_name == 'gl':
+ file.write(' {\n')
+ file.write(' GLenum _error = g_driver_gl.debug_fn.glGetErrorFn();\n')
+ file.write(' DCHECK(_error == 0);\n')
+ file.write(' }\n')
file.write(' return result;\n')
file.write('}\n')
file.write('} // extern "C"\n')
@@ -2448,6 +2462,9 @@ def main(argv):
parser = optparse.OptionParser()
parser.add_option('--inputs', action='store_true')
parser.add_option('--verify-order', action='store_true')
+ parser.add_option('--generate-dchecks', action='store_true',
+ help='Generates DCHECKs into the logging functions '
+ 'asserting no GL errors (useful for debugging)')
options, args = parser.parse_args(argv)
@@ -2512,7 +2529,7 @@ def main(argv):
source_file = open(
os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
- GenerateSource(source_file, functions, set_name, used_extensions)
+ GenerateSource(source_file, functions, set_name, used_extensions, options)
source_file.close()
ClangFormat(source_file.name)
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc
index 726f545..54e8f34 100644
--- a/ui/gl/gl_bindings_autogen_gl.cc
+++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -226,7 +226,8 @@ void DriverGL::InitializeStaticBindings() {
GetGLProcAddress("glGetShaderSource"));
fn.glGetStringFn =
reinterpret_cast<glGetStringProc>(GetGLProcAddress("glGetString"));
- fn.glGetStringiFn = 0;
+ fn.glGetStringiFn =
+ reinterpret_cast<glGetStringiProc>(GetGLProcAddress("glGetStringi"));
fn.glGetSyncivFn = 0;
fn.glGetTexLevelParameterfvFn = 0;
fn.glGetTexLevelParameterivFn = 0;
@@ -477,6 +478,8 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) {
ext.b_GL_CHROMIUM_gles_depth_binding_hack =
extensions.find("GL_CHROMIUM_gles_depth_binding_hack ") !=
std::string::npos;
+ ext.b_GL_CHROMIUM_glgetstringi_hack =
+ extensions.find("GL_CHROMIUM_glgetstringi_hack ") != std::string::npos;
ext.b_GL_EXT_debug_marker =
extensions.find("GL_EXT_debug_marker ") != std::string::npos;
ext.b_GL_EXT_direct_state_access =
@@ -1368,13 +1371,6 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) {
DCHECK(fn.glGetShaderPrecisionFormatFn);
}
- debug_fn.glGetStringiFn = 0;
- if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
- fn.glGetStringiFn =
- reinterpret_cast<glGetStringiProc>(GetGLProcAddress("glGetStringi"));
- DCHECK(fn.glGetStringiFn);
- }
-
debug_fn.glGetSyncivFn = 0;
if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
ext.b_GL_ARB_sync) {
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h
index 4a4acc9..0494657 100644
--- a/ui/gl/gl_bindings_autogen_gl.h
+++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -898,6 +898,7 @@ struct ExtensionsGL {
bool b_GL_ARB_timer_query;
bool b_GL_ARB_vertex_array_object;
bool b_GL_CHROMIUM_gles_depth_binding_hack;
+ bool b_GL_CHROMIUM_glgetstringi_hack;
bool b_GL_EXT_debug_marker;
bool b_GL_EXT_direct_state_access;
bool b_GL_EXT_discard_framebuffer;
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
index e64d031..4795d58 100644
--- a/ui/gl/gl_context.cc
+++ b/ui/gl/gl_context.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/strings/string_util.h"
#include "base/threading/thread_local.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
@@ -84,8 +85,22 @@ void GLContext::SetUnbindFboOnMakeCurrent() {
std::string GLContext::GetExtensions() {
DCHECK(IsCurrent(NULL));
- const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
- return std::string(ext ? ext : "");
+ if (gfx::GetGLImplementation() !=
+ gfx::kGLImplementationDesktopGLCoreProfile) {
+ const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ return std::string(ext ? ext : "");
+ }
+
+ std::vector<std::string> exts;
+ GLint num_extensions = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+ for (GLint i = 0; i < num_extensions; ++i) {
+ const char* extension = reinterpret_cast<const char*>(
+ glGetStringi(GL_EXTENSIONS, i));
+ DCHECK(extension != NULL);
+ exts.push_back(extension);
+ }
+ return JoinString(exts, " ");
}
std::string GLContext::GetGLVersion() {
@@ -135,7 +150,9 @@ const GLVersionInfo* GLContext::GetVersionInfo() {
std::string version = GetGLVersion();
std::string renderer = GetGLRenderer();
version_info_ =
- make_scoped_ptr(new GLVersionInfo(version.c_str(), renderer.c_str()));
+ make_scoped_ptr(new GLVersionInfo(
+ version.c_str(), renderer.c_str(),
+ GetExtensions().c_str()));
}
return version_info_.get();
}
diff --git a/ui/gl/gl_context_cgl.cc b/ui/gl/gl_context_cgl.cc
index 102407c..2fd20a0 100644
--- a/ui/gl/gl_context_cgl.cc
+++ b/ui/gl/gl_context_cgl.cc
@@ -47,6 +47,15 @@ static CGLPixelFormatObj GetPixelFormat() {
attribs.push_back((CGLPixelFormatAttribute) kCGLRendererGenericFloatID);
g_support_renderer_switching = false;
}
+ if (GetGLImplementation() == kGLImplementationDesktopGLCoreProfile) {
+ // These constants don't exist in the 10.6 SDK against which
+ // Chromium currently compiles.
+ const int kOpenGLProfile = 99;
+ const int kOpenGL3_2Core = 0x3200;
+ attribs.push_back(static_cast<CGLPixelFormatAttribute>(kOpenGLProfile));
+ attribs.push_back(static_cast<CGLPixelFormatAttribute>(kOpenGL3_2Core));
+ }
+
attribs.push_back((CGLPixelFormatAttribute) 0);
GLint num_virtual_screens;
diff --git a/ui/gl/gl_context_mac.mm b/ui/gl/gl_context_mac.mm
index aa5516f..b20cee2 100644
--- a/ui/gl/gl_context_mac.mm
+++ b/ui/gl/gl_context_mac.mm
@@ -24,6 +24,7 @@ scoped_refptr<GLContext> GLContext::CreateGLContext(
TRACE_EVENT0("gpu", "GLContext::CreateGLContext");
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
+ case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL: {
scoped_refptr<GLContext> context;
// Note that with virtualization we might still be able to make current
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc
index 5bea3f1..6752a25 100644
--- a/ui/gl/gl_gl_api_implementation.cc
+++ b/ui/gl/gl_gl_api_implementation.cc
@@ -331,8 +331,10 @@ const GLVersionInfo* GetGLVersionInfo() {
void InitializeDynamicGLBindingsGL(GLContext* context) {
g_driver_gl.InitializeCustomDynamicBindings(context);
DCHECK(context && context->IsCurrent(NULL) && !g_version_info);
- g_version_info = new GLVersionInfo(context->GetGLVersion().c_str(),
- context->GetGLRenderer().c_str());
+ g_version_info = new GLVersionInfo(
+ context->GetGLVersion().c_str(),
+ context->GetGLRenderer().c_str(),
+ context->GetExtensions().c_str());
}
void InitializeDebugGLBindingsGL() {
@@ -435,8 +437,7 @@ void VirtualGLApi::Initialize(DriverGL* driver, GLContext* real_context) {
real_context_ = real_context;
DCHECK(real_context->IsCurrent(NULL));
- std::string ext_string(
- reinterpret_cast<const char*>(driver_->fn.glGetStringFn(GL_EXTENSIONS)));
+ std::string ext_string = real_context->GetExtensions();
std::vector<std::string> ext;
Tokenize(ext_string, " ", &ext);
diff --git a/ui/gl/gl_implementation.cc b/ui/gl/gl_implementation.cc
index 74b95b8..a307fb0 100644
--- a/ui/gl/gl_implementation.cc
+++ b/ui/gl/gl_implementation.cc
@@ -99,6 +99,7 @@ GLImplementation GetGLImplementation() {
bool HasDesktopGLFeatures() {
return kGLImplementationDesktopGL == g_gl_implementation ||
+ kGLImplementationDesktopGLCoreProfile == g_gl_implementation ||
kGLImplementationOSMesaGL == g_gl_implementation ||
kGLImplementationAppleGL == g_gl_implementation;
}
diff --git a/ui/gl/gl_implementation.h b/ui/gl/gl_implementation.h
index 7319b47..6ee43e7 100644
--- a/ui/gl/gl_implementation.h
+++ b/ui/gl/gl_implementation.h
@@ -21,6 +21,7 @@ class GLContext;
enum GLImplementation {
kGLImplementationNone,
kGLImplementationDesktopGL,
+ kGLImplementationDesktopGLCoreProfile,
kGLImplementationOSMesaGL,
kGLImplementationAppleGL,
kGLImplementationEGLGLES2,
diff --git a/ui/gl/gl_implementation_mac.cc b/ui/gl/gl_implementation_mac.cc
index d818f05..8704eb9 100644
--- a/ui/gl/gl_implementation_mac.cc
+++ b/ui/gl/gl_implementation_mac.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/base_paths.h"
+#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
@@ -22,6 +23,10 @@ const char kOpenGLFrameworkPath[] =
} // namespace
void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableUnsafeES3APIs)) {
+ impls->push_back(kGLImplementationDesktopGLCoreProfile);
+ }
impls->push_back(kGLImplementationDesktopGL);
impls->push_back(kGLImplementationAppleGL);
impls->push_back(kGLImplementationOSMesaGL);
@@ -82,6 +87,7 @@ bool InitializeStaticGLBindings(GLImplementation implementation) {
break;
}
case kGLImplementationDesktopGL:
+ case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL: {
base::NativeLibrary library = base::LoadNativeLibrary(
base::FilePath(kOpenGLFrameworkPath), NULL);
@@ -113,6 +119,7 @@ bool InitializeDynamicGLBindings(GLImplementation implementation,
switch (implementation) {
case kGLImplementationOSMesaGL:
case kGLImplementationDesktopGL:
+ case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL:
InitializeDynamicGLBindingsGL(context);
break;
diff --git a/ui/gl/gl_surface_mac.cc b/ui/gl/gl_surface_mac.cc
index 4ba560d..85e9714 100644
--- a/ui/gl/gl_surface_mac.cc
+++ b/ui/gl/gl_surface_mac.cc
@@ -95,6 +95,7 @@ bool InitializeOneOffForSandbox() {
bool GLSurface::InitializeOneOffInternal() {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
+ case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL:
if (!InitializeOneOffForSandbox()) {
LOG(ERROR) << "GLSurfaceCGL::InitializeOneOff failed.";
@@ -112,6 +113,7 @@ scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
TRACE_EVENT0("gpu", "GLSurface::CreateViewGLSurface");
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
+ case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL: {
NOTIMPLEMENTED() << "No onscreen support on Mac.";
return NULL;
@@ -143,6 +145,7 @@ scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
return surface;
}
case kGLImplementationDesktopGL:
+ case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL: {
scoped_refptr<GLSurface> surface(new NoOpGLSurface(size));
if (!surface->Initialize())
diff --git a/ui/gl/gl_version_info.cc b/ui/gl/gl_version_info.cc
index e2aa0de..415faf3 100644
--- a/ui/gl/gl_version_info.cc
+++ b/ui/gl/gl_version_info.cc
@@ -10,33 +10,64 @@
namespace gfx {
+GLVersionInfo::GLVersionInfo(const char* version_str, const char* renderer_str,
+ const char* extensions_str)
+ : GLVersionInfo(version_str, renderer_str) {
+ is_desktop_core_profile =
+ !is_es && major_version >= 3 &&
+ !strstr(extensions_str, "GL_ARB_compatibility");
+}
+
+GLVersionInfo::GLVersionInfo(const char* version_str, const char* renderer_str,
+ const std::set<std::string>& extensions)
+ : GLVersionInfo(version_str, renderer_str) {
+ is_desktop_core_profile =
+ !is_es && major_version >= 3 &&
+ extensions.find("GL_ARB_compatibility") == extensions.end();
+}
+
GLVersionInfo::GLVersionInfo(const char* version_str, const char* renderer_str)
: is_es(false),
is_angle(false),
major_version(0),
minor_version(0),
- is_es3(false) {
+ is_es3(false),
+ is_desktop_core_profile(false) {
if (version_str) {
- std::string lstr(base::StringToLowerASCII(std::string(version_str)));
- is_es = (lstr.length() > 12) && (lstr.substr(0, 9) == "opengl es");
- if (is_es)
- lstr = lstr.substr(10, 3);
- base::StringTokenizer tokenizer(lstr.begin(), lstr.end(), ".");
- unsigned major, minor;
- if (tokenizer.GetNext() &&
- base::StringToUint(tokenizer.token_piece(), &major)) {
- major_version = major;
- if (tokenizer.GetNext() &&
- base::StringToUint(tokenizer.token_piece(), &minor)) {
- minor_version = minor;
- }
- }
- if (is_es && major_version == 3)
- is_es3 = true;
+ ParseVersionString(version_str, &major_version, &minor_version,
+ &is_es, &is_es3);
}
if (renderer_str) {
is_angle = StartsWithASCII(renderer_str, "ANGLE", true);
}
}
+void GLVersionInfo::ParseVersionString(const char* version_str,
+ unsigned* major_version,
+ unsigned* minor_version,
+ bool* is_es,
+ bool* is_es3) {
+ // Make sure the outputs are always initialized.
+ *major_version = 0;
+ *minor_version = 0;
+ *is_es = false;
+ *is_es3 = false;
+ std::string lstr(base::StringToLowerASCII(std::string(version_str)));
+ *is_es = (lstr.length() > 12) && (lstr.substr(0, 9) == "opengl es");
+ if (*is_es)
+ lstr = lstr.substr(10, 3);
+ base::StringTokenizer tokenizer(lstr.begin(), lstr.end(), ".");
+ unsigned major, minor;
+ if (tokenizer.GetNext() &&
+ base::StringToUint(tokenizer.token_piece(), &major)) {
+ *major_version = major;
+ if (tokenizer.GetNext() &&
+ base::StringToUint(tokenizer.token_piece(), &minor)) {
+ *minor_version = minor;
+ }
+ }
+ if (*is_es && *major_version == 3)
+ *is_es3 = true;
+}
+
} // namespace gfx
diff --git a/ui/gl/gl_version_info.h b/ui/gl/gl_version_info.h
index d8f2730..1bfca20 100644
--- a/ui/gl/gl_version_info.h
+++ b/ui/gl/gl_version_info.h
@@ -5,6 +5,7 @@
#ifndef UI_GL_GL_VERSION_INFO_H_
#define UI_GL_GL_VERSION_INFO_H_
+#include <set>
#include <string>
#include "base/basictypes.h"
#include "ui/gl/gl_export.h"
@@ -12,7 +13,11 @@
namespace gfx {
struct GL_EXPORT GLVersionInfo {
- GLVersionInfo(const char* version_str, const char* renderer_str);
+ GLVersionInfo(const char* version_str, const char* renderer_str,
+ const char* extensions_str);
+
+ GLVersionInfo(const char* version_str, const char* renderer_str,
+ const std::set<std::string>& exts);
bool IsAtLeastGL(unsigned major, unsigned minor) const {
return !is_es && (major_version > major ||
@@ -24,13 +29,26 @@ struct GL_EXPORT GLVersionInfo {
(major_version == major && minor_version >= minor));
}
+ bool BehavesLikeGLES() const {
+ return is_es || is_desktop_core_profile;
+ }
+
+ static void ParseVersionString(const char* version_str,
+ unsigned* major_version,
+ unsigned* minor_version,
+ bool* is_es,
+ bool* is_es3);
+
bool is_es;
bool is_angle;
unsigned major_version;
unsigned minor_version;
bool is_es3;
+ bool is_desktop_core_profile;
private:
+ GLVersionInfo(const char* version_str, const char* renderer_str);
+
DISALLOW_COPY_AND_ASSIGN(GLVersionInfo);
};