0

command_buffer: Add support for creating non-WebGL ES 3 contexts

Add support for creating non-WebGL ES 3 contexts.

Replaces "web gl version" in context creation attributes with
"context type".

Adds an example use-case, a GL test that uses ES 3.0 context.

Makes it possible to use ES 3.0 functions exposed by command buffer.
Previously the ES 3.0 functions were removed by the linker.

Needed, because up-coming features might have ES 3.0 related code,
and that code needs to be tested. EXT_blend_func_extended is an
example of such a feature.

BUG=506765

Review URL: https://codereview.chromium.org/1325433003

Cr-Commit-Position: refs/heads/master@{#350319}
This commit is contained in:
kkinnunen
2015-09-22 23:39:04 -07:00
committed by Commit bot
parent 75f515b07a
commit 631033e40b
23 changed files with 210 additions and 151 deletions

@ -58,7 +58,7 @@ BlimpContextProvider::BlimpContextProvider(gfx::AcceleratedWidget widget) {
attribs_for_gles2.sample_buffers = 0;
attribs_for_gles2.fail_if_major_perf_caveat = false;
attribs_for_gles2.bind_generates_resource = false;
attribs_for_gles2.webgl_version = 0;
attribs_for_gles2.context_type = gpu::gles2::CONTEXT_TYPE_OPENGLES2;
attribs_for_gles2.lose_context_when_out_of_memory = true;
context_.reset(gpu::GLInProcessContext::Create(

@ -32,15 +32,7 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
// TODO(penghuang): Support share context.
// TODO(penghuang): Fill gl_info.
gpu::gles2::ContextCreationAttribHelper attrib_helper;
attrib_helper.alpha_size = attributes.alpha ? 8 : 0;
attrib_helper.depth_size = attributes.depth ? 24 : 0;
attrib_helper.stencil_size = attributes.stencil ? 8 : 0;
attrib_helper.samples = attributes.antialias ? 4 : 0;
attrib_helper.sample_buffers = attributes.antialias ? 1 : 0;
attrib_helper.fail_if_major_perf_caveat =
attributes.failIfMajorPerformanceCaveat;
attrib_helper.bind_generates_resource = false;
attrib_helper.webgl_version = attributes.webGLVersion;
ConvertAttributes(attributes, &attrib_helper);
std::vector<int32_t> attrib_vector;
attrib_helper.Serialize(&attrib_vector);
gles2_context_ = MojoGLES2CreateContext(

@ -118,6 +118,7 @@ group("gl_tests_run") {
test("gl_tests") {
sources = [
"command_buffer/tests/compressed_texture_test.cc",
"command_buffer/tests/es3_misc_functions_unittest.cc",
"command_buffer/tests/gl_bind_uniform_location_unittest.cc",
"command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc",
"command_buffer/tests/gl_chromium_path_rendering_unittest.cc",

@ -1254,7 +1254,21 @@ void WebGraphicsContext3DImpl::ConvertAttributes(
output_attribs->fail_if_major_perf_caveat =
attributes.failIfMajorPerformanceCaveat;
output_attribs->bind_generates_resource = false;
output_attribs->webgl_version = attributes.webGLVersion;
switch (attributes.webGLVersion) {
case 0:
output_attribs->context_type = ::gpu::gles2::CONTEXT_TYPE_OPENGLES2;
break;
case 1:
output_attribs->context_type = ::gpu::gles2::CONTEXT_TYPE_WEBGL1;
break;
case 2:
output_attribs->context_type = ::gpu::gles2::CONTEXT_TYPE_WEBGL2;
break;
default:
NOTREACHED();
output_attribs->context_type = ::gpu::gles2::CONTEXT_TYPE_OPENGLES2;
break;
}
}
} // namespace gpu_blink

@ -12,6 +12,7 @@
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include <GLES3/gl3.h>
#include <stddef.h>
extern "C" {

@ -1235,7 +1235,7 @@ const int32 kBufferDestroyed = 0x3095; // EGL_BUFFER_DESTROYED
const int32 kBindGeneratesResource = 0x10000;
const int32 kFailIfMajorPerfCaveat = 0x10001;
const int32 kLoseContextWhenOutOfMemory = 0x10002;
const int32 kWebGLVersion = 0x10003;
const int32 kContextType = 0x10003;
} // namespace
@ -1252,8 +1252,7 @@ ContextCreationAttribHelper::ContextCreationAttribHelper()
bind_generates_resource(true),
fail_if_major_perf_caveat(false),
lose_context_when_out_of_memory(false),
webgl_version(0) {
}
context_type(CONTEXT_TYPE_OPENGLES2) {}
void ContextCreationAttribHelper::Serialize(std::vector<int32>* attribs) const {
if (alpha_size != -1) {
@ -1296,8 +1295,8 @@ void ContextCreationAttribHelper::Serialize(std::vector<int32>* attribs) const {
attribs->push_back(fail_if_major_perf_caveat ? 1 : 0);
attribs->push_back(kLoseContextWhenOutOfMemory);
attribs->push_back(lose_context_when_out_of_memory ? 1 : 0);
attribs->push_back(kWebGLVersion);
attribs->push_back(webgl_version);
attribs->push_back(kContextType);
attribs->push_back(context_type);
attribs->push_back(kNone);
}
@ -1352,8 +1351,8 @@ bool ContextCreationAttribHelper::Parse(const std::vector<int32>& attribs) {
case kLoseContextWhenOutOfMemory:
lose_context_when_out_of_memory = value != 0;
break;
case kWebGLVersion:
webgl_version = value;
case kContextType:
context_type = static_cast<ContextType>(value);
break;
case kNone:
// Terminate list, even if more attributes.

@ -204,6 +204,13 @@ class GLES2_UTILS_EXPORT GLES2Util {
int num_shader_binary_formats_;
};
enum ContextType {
CONTEXT_TYPE_WEBGL1,
CONTEXT_TYPE_WEBGL2,
CONTEXT_TYPE_OPENGLES2,
CONTEXT_TYPE_OPENGLES3
};
struct GLES2_UTILS_EXPORT ContextCreationAttribHelper {
ContextCreationAttribHelper();
@ -223,8 +230,7 @@ struct GLES2_UTILS_EXPORT ContextCreationAttribHelper {
bool bind_generates_resource;
bool fail_if_major_perf_caveat;
bool lose_context_when_out_of_memory;
// 0 if not a WebGL context.
unsigned webgl_version;
ContextType context_type;
};
} // namespace gles2

@ -36,7 +36,7 @@ ContextGroup::ContextGroup(
const scoped_refptr<SubscriptionRefSet>& subscription_ref_set,
const scoped_refptr<ValueStateMap>& pending_valuebuffer_state,
bool bind_generates_resource)
: context_type_(CONTEXT_TYPE_UNDEFINED),
: context_type_(CONTEXT_TYPE_OPENGLES2),
mailbox_manager_(mailbox_manager),
memory_tracker_(memory_tracker),
shader_translator_cache_(shader_translator_cache),
@ -89,31 +89,10 @@ static void GetIntegerv(GLenum pname, uint32* var) {
*var = value;
}
// static
ContextGroup::ContextType ContextGroup::GetContextType(
unsigned webgl_version) {
switch (webgl_version) {
case 0:
return CONTEXT_TYPE_OTHER;
case 1:
return CONTEXT_TYPE_WEBGL1;
case 2:
return CONTEXT_TYPE_WEBGL2;
default:
return CONTEXT_TYPE_UNDEFINED;
}
}
bool ContextGroup::Initialize(
GLES2Decoder* decoder,
ContextGroup::ContextType context_type,
const DisallowedFeatures& disallowed_features) {
if (context_type == CONTEXT_TYPE_UNDEFINED) {
LOG(ERROR) << "ContextGroup::Initialize failed because of unknown "
<< "context type.";
return false;
}
if (context_type_ == CONTEXT_TYPE_UNDEFINED) {
bool ContextGroup::Initialize(GLES2Decoder* decoder,
ContextType context_type,
const DisallowedFeatures& disallowed_features) {
if (!HaveContexts()) {
context_type_ = context_type;
} else if (context_type_ != context_type) {
LOG(ERROR) << "ContextGroup::Initialize failed because the type of "

@ -13,6 +13,7 @@
#include "base/memory/weak_ptr.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
#include "gpu/command_buffer/service/shader_translator_cache.h"
@ -44,15 +45,6 @@ struct DisallowedFeatures;
// resources.
class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
public:
enum ContextType {
CONTEXT_TYPE_WEBGL1,
CONTEXT_TYPE_WEBGL2,
CONTEXT_TYPE_OTHER,
CONTEXT_TYPE_UNDEFINED
};
static ContextType GetContextType(unsigned webgl_version);
ContextGroup(
const scoped_refptr<MailboxManager>& mailbox_manager,
const scoped_refptr<MemoryTracker>& memory_tracker,

@ -68,8 +68,8 @@ TEST_F(ContextGroupTest, Basic) {
TEST_F(ContextGroupTest, InitializeNoExtensions) {
TestHelper::SetupContextGroupInitExpectations(
gl_.get(), DisallowedFeatures(), "", "", kBindGeneratesResource);
group_->Initialize(
decoder_.get(), ContextGroup::CONTEXT_TYPE_OTHER, DisallowedFeatures());
group_->Initialize(decoder_.get(), CONTEXT_TYPE_OPENGLES2,
DisallowedFeatures());
EXPECT_EQ(static_cast<uint32>(TestHelper::kNumVertexAttribs),
group_->max_vertex_attribs());
EXPECT_EQ(static_cast<uint32>(TestHelper::kNumTextureUnits),
@ -104,19 +104,16 @@ TEST_F(ContextGroupTest, MultipleContexts) {
scoped_ptr<MockGLES2Decoder> decoder2_(new MockGLES2Decoder());
TestHelper::SetupContextGroupInitExpectations(
gl_.get(), DisallowedFeatures(), "", "", kBindGeneratesResource);
EXPECT_TRUE(group_->Initialize(
decoder_.get(), ContextGroup::CONTEXT_TYPE_OTHER, DisallowedFeatures()));
EXPECT_FALSE(group_->Initialize(
decoder2_.get(), ContextGroup::CONTEXT_TYPE_WEBGL1,
DisallowedFeatures()));
EXPECT_FALSE(group_->Initialize(
decoder2_.get(), ContextGroup::CONTEXT_TYPE_WEBGL2,
DisallowedFeatures()));
EXPECT_FALSE(group_->Initialize(
decoder2_.get(), ContextGroup::CONTEXT_TYPE_UNDEFINED,
DisallowedFeatures()));
EXPECT_TRUE(group_->Initialize(
decoder2_.get(), ContextGroup::CONTEXT_TYPE_OTHER, DisallowedFeatures()));
EXPECT_TRUE(group_->Initialize(decoder_.get(), CONTEXT_TYPE_OPENGLES2,
DisallowedFeatures()));
EXPECT_FALSE(group_->Initialize(decoder2_.get(), CONTEXT_TYPE_WEBGL1,
DisallowedFeatures()));
EXPECT_FALSE(group_->Initialize(decoder2_.get(), CONTEXT_TYPE_WEBGL2,
DisallowedFeatures()));
EXPECT_FALSE(group_->Initialize(decoder2_.get(), CONTEXT_TYPE_OPENGLES3,
DisallowedFeatures()));
EXPECT_TRUE(group_->Initialize(decoder2_.get(), CONTEXT_TYPE_OPENGLES2,
DisallowedFeatures()));
EXPECT_TRUE(group_->buffer_manager() != NULL);
EXPECT_TRUE(group_->framebuffer_manager() != NULL);

@ -245,7 +245,7 @@ FramebufferManager::TextureDetachObserver::~TextureDetachObserver() {}
FramebufferManager::FramebufferManager(
uint32 max_draw_buffers,
uint32 max_color_attachments,
ContextGroup::ContextType context_type,
ContextType context_type,
const scoped_refptr<FramebufferCompletenessCache>&
framebuffer_combo_complete_cache)
: framebuffer_state_change_count_(1),
@ -491,7 +491,7 @@ GLenum Framebuffer::IsPossiblyComplete() const {
if (width == 0 || height == 0) {
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
} else if (manager_->context_type() != ContextGroup::CONTEXT_TYPE_WEBGL2) {
} else if (manager_->context_type() != CONTEXT_TYPE_WEBGL2) {
// TODO(zmo): revisit this if we create ES3 contexts for clients other
// than WebGL 2.
if (attachment->width() != width || attachment->height() != height) {

@ -255,7 +255,7 @@ class GPU_EXPORT FramebufferManager {
FramebufferManager(uint32 max_draw_buffers,
uint32 max_color_attachments,
ContextGroup::ContextType context_type,
ContextType context_type,
const scoped_refptr<FramebufferCompletenessCache>&
framebuffer_combo_complete_cache);
~FramebufferManager();
@ -302,9 +302,7 @@ class GPU_EXPORT FramebufferManager {
texture_detach_observers_.end());
}
ContextGroup::ContextType context_type() const {
return context_type_;
}
ContextType context_type() const { return context_type_; }
private:
friend class Framebuffer;
@ -336,7 +334,7 @@ class GPU_EXPORT FramebufferManager {
uint32 max_draw_buffers_;
uint32 max_color_attachments_;
ContextGroup::ContextType context_type_;
ContextType context_type_;
typedef std::vector<TextureDetachObserver*> TextureDetachObserverVector;
TextureDetachObserverVector texture_detach_observers_;

@ -34,7 +34,7 @@ const bool kUseDefaultTextures = false;
class FramebufferManagerTest : public GpuServiceTest {
public:
FramebufferManagerTest()
: manager_(1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED, NULL),
: manager_(1, 1, CONTEXT_TYPE_OPENGLES2, NULL),
feature_info_(new FeatureInfo()) {
texture_manager_.reset(new TextureManager(NULL,
feature_info_.get(),
@ -110,7 +110,7 @@ class FramebufferInfoTestBase : public GpuServiceTest {
static const GLuint kClient1Id = 1;
static const GLuint kService1Id = 11;
explicit FramebufferInfoTestBase(ContextGroup::ContextType context_type)
explicit FramebufferInfoTestBase(ContextType context_type)
: manager_(kMaxDrawBuffers,
kMaxColorAttachments,
context_type,
@ -160,9 +160,7 @@ class FramebufferInfoTestBase : public GpuServiceTest {
class FramebufferInfoTest : public FramebufferInfoTestBase {
public:
FramebufferInfoTest()
: FramebufferInfoTestBase(ContextGroup::CONTEXT_TYPE_UNDEFINED) {
}
FramebufferInfoTest() : FramebufferInfoTestBase(CONTEXT_TYPE_OPENGLES2) {}
};
// GCC requires these declarations, but MSVC requires they not be present
@ -905,9 +903,7 @@ TEST_F(FramebufferInfoTest, GetStatus) {
class FramebufferInfoES3Test : public FramebufferInfoTestBase {
public:
FramebufferInfoES3Test()
: FramebufferInfoTestBase(ContextGroup::CONTEXT_TYPE_WEBGL2) {
}
FramebufferInfoES3Test() : FramebufferInfoTestBase(CONTEXT_TYPE_WEBGL2) {}
};
TEST_F(FramebufferInfoES3Test, DifferentDimensions) {

@ -842,7 +842,8 @@ class GLES2DecoderImpl : public GLES2Decoder,
}
bool IsWebGLContext() const {
return webgl_version_ == 1 || webgl_version_ == 2;
return context_type_ == CONTEXT_TYPE_WEBGL1 ||
context_type_ == CONTEXT_TYPE_WEBGL2;
}
bool IsOffscreenBufferMultisampled() const {
@ -2038,11 +2039,7 @@ class GLES2DecoderImpl : public GLES2Decoder,
bool reset_by_robustness_extension_;
bool supports_post_sub_buffer_;
// Indicates whether this is a context for WebGL1, WebGL2, or others.
// 0: other types
// 1: WebGL 1
// 2: WebGL 2
unsigned webgl_version_;
ContextType context_type_;
// These flags are used to override the state of the shared feature_info_
// member. Because the same FeatureInfo instance may be shared among many
@ -2582,7 +2579,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
context_was_lost_(false),
reset_by_robustness_extension_(false),
supports_post_sub_buffer_(false),
webgl_version_(0),
context_type_(CONTEXT_TYPE_OPENGLES2),
derivatives_explicitly_enabled_(false),
frag_depth_explicitly_enabled_(false),
draw_buffers_explicitly_enabled_(false),
@ -2625,7 +2622,8 @@ bool GLES2DecoderImpl::Initialize(
ContextCreationAttribHelper attrib_parser;
if (!attrib_parser.Parse(attribs))
return false;
webgl_version_ = attrib_parser.webgl_version;
context_type_ = attrib_parser.context_type;
surfaceless_ = surface->IsSurfaceless() && !offscreen;
@ -2676,20 +2674,18 @@ bool GLES2DecoderImpl::Initialize(
}
disallowed_features_ = disallowed_features;
if (webgl_version_ == 1) {
if (context_type_ == CONTEXT_TYPE_WEBGL1) {
disallowed_features_.npot_support = true;
}
if (!group_->Initialize(this,
ContextGroup::GetContextType(webgl_version_),
disallowed_features_)) {
if (!group_->Initialize(this, context_type_, disallowed_features_)) {
group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
Destroy(true);
return false;
}
CHECK_GL_ERROR();
if (webgl_version_ == 2) {
if (context_type_ == CONTEXT_TYPE_WEBGL2 ||
context_type_ == CONTEXT_TYPE_OPENGLES3) {
if (!feature_info_->IsES3Capable()) {
LOG(ERROR) << "Underlying driver does not support ES3.";
Destroy(true);
@ -3264,10 +3260,23 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
}
ShShaderSpec shader_spec;
if (IsWebGLContext()) {
shader_spec = webgl_version_ == 2 ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
} else {
shader_spec = unsafe_es3_apis_enabled() ? SH_GLES3_SPEC : SH_GLES2_SPEC;
switch (context_type_) {
case CONTEXT_TYPE_WEBGL1:
shader_spec = SH_WEBGL_SPEC;
break;
case CONTEXT_TYPE_WEBGL2:
shader_spec = SH_WEBGL2_SPEC;
break;
case CONTEXT_TYPE_OPENGLES2:
shader_spec = SH_GLES2_SPEC;
break;
case CONTEXT_TYPE_OPENGLES3:
shader_spec = SH_GLES3_SPEC;
break;
default:
NOTREACHED();
shader_spec = SH_GLES2_SPEC;
break;
}
if ((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) &&

@ -93,7 +93,7 @@ void GLES3DecoderTest::SetUp() {
InitState init;
init.gl_version = "OpenGL ES 3.0";
init.bind_generates_resource = true;
init.webgl_version = 2;
init.context_type = CONTEXT_TYPE_OPENGLES3;
InitDecoderWithCommandLine(init, &command_line);
}

@ -160,8 +160,7 @@ GLES2DecoderTestBase::InitState::InitState()
bind_generates_resource(false),
lose_context_when_out_of_memory(false),
use_native_vao(true),
webgl_version(0) {
}
context_type(CONTEXT_TYPE_OPENGLES2) {}
void GLES2DecoderTestBase::InitDecoder(const InitState& init) {
InitDecoderWithCommandLine(init, NULL);
@ -225,13 +224,11 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine(
EXPECT_CALL(*mock_decoder_, DoCommands(_, _, _, _)).WillRepeatedly(
Invoke(mock_decoder_.get(), &MockGLES2Decoder::FakeDoCommands));
EXPECT_TRUE(group_->Initialize(mock_decoder_.get(), init.context_type,
DisallowedFeatures()));
EXPECT_TRUE(group_->Initialize(
mock_decoder_.get(),
ContextGroup::GetContextType(init.webgl_version),
DisallowedFeatures()));
if (init.webgl_version == 2) {
if (init.context_type == CONTEXT_TYPE_WEBGL2 ||
init.context_type == CONTEXT_TYPE_OPENGLES3) {
EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS, _))
.WillOnce(SetArgumentPointee<1>(kMaxColorAttachments))
.RetiresOnSaturation();
@ -403,29 +400,25 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine(
static const int32 kLoseContextWhenOutOfMemory = 0x10002;
static const int32 kWebGLVersion = 0x10003;
int32 attributes[] = {
EGL_ALPHA_SIZE,
normalized_init.request_alpha ? 8 : 0,
EGL_DEPTH_SIZE,
normalized_init.request_depth ? 24 : 0,
EGL_STENCIL_SIZE,
normalized_init.request_stencil ? 8 : 0,
kLoseContextWhenOutOfMemory,
normalized_init.lose_context_when_out_of_memory ? 1 : 0,
kWebGLVersion,
init.webgl_version
};
int32 attributes[] = {EGL_ALPHA_SIZE,
normalized_init.request_alpha ? 8 : 0,
EGL_DEPTH_SIZE,
normalized_init.request_depth ? 24 : 0,
EGL_STENCIL_SIZE,
normalized_init.request_stencil ? 8 : 0,
kLoseContextWhenOutOfMemory,
normalized_init.lose_context_when_out_of_memory ? 1 : 0,
kWebGLVersion,
init.context_type};
std::vector<int32> attribs(attributes, attributes + arraysize(attributes));
decoder_.reset(GLES2Decoder::Create(group_.get()));
decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_);
decoder_->GetLogger()->set_log_synthesized_gl_errors(false);
decoder_->Initialize(surface_,
context_,
false,
surface_->GetSize(),
DisallowedFeatures(),
attribs);
ASSERT_TRUE(decoder_->Initialize(surface_, context_, false,
surface_->GetSize(), DisallowedFeatures(),
attribs));
EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true));
if (context_->WasAllocatedUsingRobustnessExtension()) {
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())

@ -200,7 +200,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> {
bool bind_generates_resource;
bool lose_context_when_out_of_memory;
bool use_native_vao; // default is true.
unsigned webgl_version; // default to 0, i.e., not WebGL context.
ContextType context_type;
};
void InitDecoder(const InitState& init);

@ -1962,11 +1962,11 @@ TEST_F(SharedTextureTest, TextureSafetyAccounting) {
TEST_F(SharedTextureTest, FBOCompletenessCheck) {
const GLenum kCompleteValue = GL_FRAMEBUFFER_COMPLETE;
FramebufferManager framebuffer_manager1(
1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED, NULL);
FramebufferManager framebuffer_manager1(1, 1, CONTEXT_TYPE_OPENGLES2,
nullptr);
texture_manager1_->set_framebuffer_manager(&framebuffer_manager1);
FramebufferManager framebuffer_manager2(
1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED, NULL);
FramebufferManager framebuffer_manager2(1, 1, CONTEXT_TYPE_OPENGLES2,
nullptr);
texture_manager2_->set_framebuffer_manager(&framebuffer_manager2);
scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10);

@ -0,0 +1,83 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include <GLES3/gl3.h>
#include "base/command_line.h"
#include "gpu/command_buffer/tests/gl_manager.h"
#include "gpu/command_buffer/tests/gl_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_switches.h"
#define SHADER_VERSION_300(Src) "#version 300 es\n" #Src
namespace gpu {
class OpenGLES3FunctionTest : public testing::Test {
protected:
void SetUp() override {
base::CommandLine command_line(*base::CommandLine::ForCurrentProcess());
command_line.AppendSwitch(switches::kEnableUnsafeES3APIs);
GLManager::Options options;
options.context_type = gles2::CONTEXT_TYPE_OPENGLES3;
gl_.InitializeWithCommandLine(options, &command_line);
}
void TearDown() override { gl_.Destroy(); }
bool IsApplicable() const { return gl_.IsInitialized(); }
GLManager gl_;
};
TEST_F(OpenGLES3FunctionTest, GetFragDataLocationInvalid) {
if (!IsApplicable()) {
return;
}
// clang-format off
static const char* kVertexShader =
SHADER_VERSION_300(
in vec4 position;
void main() {
gl_Position = position;
});
static const char* kFragColorShader =
SHADER_VERSION_300(
precision mediump float;
uniform vec4 src;
out vec4 FragColor;
void main() {
FragColor = src;
});
// clang-format on
GLuint vsid = GLTestHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader);
GLuint fsid = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, kFragColorShader);
GLuint program = glCreateProgram();
glAttachShader(program, vsid);
glAttachShader(program, fsid);
glDeleteShader(vsid);
glDeleteShader(fsid);
GLint location = glGetFragDataLocation(program, "FragColor");
EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
EXPECT_EQ(-1, location);
location = glGetFragDataLocation(program, "Unknown");
EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
EXPECT_EQ(-1, location);
glLinkProgram(program);
location = glGetFragDataLocation(program, "FragColor");
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
EXPECT_EQ(0, location);
location = glGetFragDataLocation(program, "Unknown");
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
EXPECT_EQ(-1, location);
glDeleteProgram(program);
}
} // namespace gpu

@ -109,8 +109,7 @@ GLManager::Options::Options()
bind_generates_resource(false),
lose_context_when_out_of_memory(false),
context_lost_allowed(false),
webgl_version(0) {
}
context_type(gles2::CONTEXT_TYPE_OPENGLES2) {}
GLManager::GLManager() : context_lost_allowed_(false) {
SetupBaseContext();
@ -197,7 +196,8 @@ void GLManager::InitializeWithCommandLine(const GLManager::Options& options,
attrib_helper.alpha_size = 8;
attrib_helper.depth_size = 16;
attrib_helper.stencil_size = 8;
attrib_helper.webgl_version = options.webgl_version;
attrib_helper.context_type = options.context_type;
attrib_helper.Serialize(&attribs);
DCHECK(!command_line || !context_group);
@ -248,13 +248,10 @@ void GLManager::InitializeWithCommandLine(const GLManager::Options& options,
ASSERT_TRUE(context_->MakeCurrent(surface_.get()));
ASSERT_TRUE(decoder_->Initialize(
surface_.get(),
context_.get(),
true,
options.size,
::gpu::gles2::DisallowedFeatures(),
attribs)) << "could not initialize decoder";
if (!decoder_->Initialize(surface_.get(), context_.get(), true, options.size,
::gpu::gles2::DisallowedFeatures(), attribs)) {
return;
}
command_buffer_->SetPutOffsetChangeCallback(
base::Bind(&GLManager::PumpCommands, base::Unretained(this)));
@ -326,7 +323,8 @@ void GLManager::Destroy() {
gles2_helper_.reset();
command_buffer_.reset();
if (decoder_.get()) {
bool have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get());
bool have_context = decoder_->GetGLContext() &&
decoder_->GetGLContext()->MakeCurrent(surface_.get());
decoder_->Destroy(have_context);
decoder_.reset();
}

@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
@ -61,10 +62,7 @@ class GLManager : private GpuControl {
bool lose_context_when_out_of_memory;
// Whether or not it's ok to lose the context.
bool context_lost_allowed;
// 0 indicates not WebGL context - default.
// 1 indicates WebGL 1 context.
// 2 indicates WebGL 2 context.
unsigned webgl_version;
gles2::ContextType context_type;
};
GLManager();
~GLManager() override;
@ -78,6 +76,8 @@ class GLManager : private GpuControl {
base::CommandLine* command_line);
void Destroy();
bool IsInitialized() const { return gles2_implementation() != nullptr; }
void MakeCurrent();
void SetSurface(gfx::GLSurface* surface);

@ -29,7 +29,7 @@ class WebGLProgramTest : public GLProgramTest {
protected:
void SetUp() override {
GLManager::Options options;
options.webgl_version = 1;
options.context_type = gles2::CONTEXT_TYPE_WEBGL1;
gl_.Initialize(options);
}
};

@ -350,6 +350,7 @@
'sources': [
# Note: sources list duplicated in GN build.
'command_buffer/tests/compressed_texture_test.cc',
'command_buffer/tests/es3_misc_functions_unittest.cc',
'command_buffer/tests/gl_bind_uniform_location_unittest.cc',
'command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc',
'command_buffer/tests/gl_chromium_path_rendering_unittest.cc',