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

Unified Diff: gpu/gles2_conform_support/egl/display.cc

Issue 1714883002: command_buffer_gles2: Implement EGL default Display as a global object (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@command_buffer_gles2-multiple-contexts
Patch Set: rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/gles2_conform_support/egl/display.h ('k') | gpu/gles2_conform_support/egl/egl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/gles2_conform_support/egl/display.cc
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index f12c94257376c4a3298655a9b4ca082964b98902..b4e01587fd4144d0272380f49a9b153802849211 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -4,134 +4,115 @@
#include "gpu/gles2_conform_support/egl/display.h"
-#include <stddef.h>
-#include <stdint.h>
-
-#include <vector>
-#include "base/at_exit.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/lazy_instance.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/command_buffer/client/shared_memory_limits.h"
-#include "gpu/command_buffer/client/transfer_buffer.h"
-#include "gpu/command_buffer/service/context_group.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-#include "gpu/command_buffer/service/transfer_buffer_manager.h"
#include "gpu/gles2_conform_support/egl/config.h"
+#include "gpu/gles2_conform_support/egl/context.h"
#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/test_support.h"
-
-namespace {
-const int32_t kCommandBufferSize = 1024 * 1024;
-const int32_t kTransferBufferSize = 512 * 1024;
-}
+#include "gpu/gles2_conform_support/egl/thread_state.h"
namespace egl {
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-// egl::Display is used for comformance tests and command_buffer_gles. We only
-// need the exit manager for the command_buffer_gles library.
-// TODO(hendrikw): Find a cleaner solution for this.
-namespace {
-base::LazyInstance<base::Lock>::Leaky g_exit_manager_lock;
-int g_exit_manager_use_count;
-base::AtExitManager* g_exit_manager;
-void RefAtExitManager() {
- base::AutoLock lock(g_exit_manager_lock.Get());
-#if defined(COMPONENT_BUILD)
- if (g_command_buffer_gles_has_atexit_manager) {
- return;
- }
-#endif
- if (g_exit_manager_use_count == 0) {
- g_exit_manager = new base::AtExitManager;
- }
- ++g_exit_manager_use_count;
-}
-void ReleaseAtExitManager() {
- base::AutoLock lock(g_exit_manager_lock.Get());
-#if defined(COMPONENT_BUILD)
- if (g_command_buffer_gles_has_atexit_manager) {
- return;
- }
-#endif
- --g_exit_manager_use_count;
- if (g_exit_manager_use_count == 0) {
- delete g_exit_manager;
- g_exit_manager = nullptr;
- }
-}
-}
-#endif
-
-Display::Display(EGLNativeDisplayType display_id)
- : display_id_(display_id),
- gpu_driver_bug_workarounds_(base::CommandLine::ForCurrentProcess()),
- is_initialized_(false),
- create_offscreen_(false),
- create_offscreen_width_(0),
- create_offscreen_height_(0),
- next_fence_sync_release_(1) {
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
- RefAtExitManager();
-#endif
+
+Display::Display()
+ : is_initialized_(false),
+ next_create_window_surface_creates_pbuffer_(false),
+ window_surface_pbuffer_width_(0),
+ window_surface_pbuffer_height_(0) {
}
Display::~Display() {
- gles2::Terminate();
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
- ReleaseAtExitManager();
-#endif
+ surfaces_.clear();
+ contexts_.clear();
}
-
-bool Display::Initialize() {
- gles2::Initialize();
- is_initialized_ = true;
- return true;
+void Display::SetNextCreateWindowSurfaceCreatesPBuffer(EGLint width,
+ EGLint height) {
+ next_create_window_surface_creates_pbuffer_ = true;
+ window_surface_pbuffer_width_ = width;
+ window_surface_pbuffer_height_ = height;
}
-bool Display::IsValidConfig(EGLConfig config) {
- return (config != NULL) && (config == config_.get());
-}
+EGLBoolean Display::Initialize(ThreadState* ts, EGLint* major, EGLint* minor) {
+ base::AutoLock auto_lock(lock_);
+ is_initialized_ = true;
-bool Display::ChooseConfigs(EGLConfig* configs,
- EGLint config_size,
- EGLint* num_config) {
- // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
- // does not support finding or choosing configs.
- *num_config = 1;
- if (configs != NULL) {
- if (config_ == NULL) {
- config_.reset(new Config);
- }
- configs[0] = config_.get();
+ if (major)
+ *major = 1;
+ if (minor)
+ *minor = 4;
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+EGLBoolean Display::Terminate(ThreadState* ts) {
+ base::AutoLock auto_lock(lock_);
+ is_initialized_ = false;
+ surfaces_.clear();
+ for (const auto& context : contexts_)
+ context->MarkDestroyed();
+ contexts_.clear();
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+const char* Display::QueryString(ThreadState* ts, EGLint name) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError<const char*>(EGL_NOT_INITIALIZED, nullptr);
+ switch (name) {
+ case EGL_CLIENT_APIS:
+ return ts->ReturnSuccess("OpenGL_ES");
+ case EGL_EXTENSIONS:
+ return ts->ReturnSuccess("");
+ case EGL_VENDOR:
+ return ts->ReturnSuccess("Google Inc.");
+ case EGL_VERSION:
+ return ts->ReturnSuccess("1.4");
+ default:
+ return ts->ReturnError<const char*>(EGL_BAD_PARAMETER, nullptr);
}
- return true;
}
-bool Display::GetConfigs(EGLConfig* configs,
- EGLint config_size,
- EGLint* num_config) {
- // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
- // does not support finding or choosing configs.
- *num_config = 1;
- if (configs != NULL) {
- if (config_ == NULL) {
- config_.reset(new Config);
+EGLBoolean Display::ChooseConfig(ThreadState* ts,
+ const EGLint* attrib_list,
+ EGLConfig* configs,
+ EGLint config_size,
+ EGLint* num_config) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ if (num_config == nullptr)
+ return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
+ if (!Config::ValidateAttributeList(attrib_list))
+ return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ InitializeConfigsIfNeeded();
+ if (!configs)
+ config_size = 0;
+ *num_config = 0;
+ for (size_t i = 0; i < arraysize(configs_); ++i) {
+ if (configs_[i]->Matches(attrib_list)) {
+ if (*num_config < config_size) {
+ configs[*num_config] = configs_[i].get();
+ }
+ ++*num_config;
}
- configs[0] = config_.get();
}
- return true;
-}
-
-bool Display::GetConfigAttrib(EGLConfig config,
- EGLint attribute,
- EGLint* value) {
- const egl::Config* cfg = static_cast<egl::Config*>(config);
- return cfg->GetAttrib(attribute, value);
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+EGLBoolean Display::GetConfigs(ThreadState* ts,
+ EGLConfig* configs,
+ EGLint config_size,
+ EGLint* num_config) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ if (num_config == nullptr)
+ return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
+ InitializeConfigsIfNeeded();
+ if (!configs)
+ config_size = 0;
+ *num_config = arraysize(configs_);
+ size_t count =
+ std::min(arraysize(configs_), static_cast<size_t>(config_size));
+ for (size_t i = 0; i < count; ++i)
+ configs[i] = configs_[i].get();
+ return ts->ReturnSuccess(EGL_TRUE);
}
bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
@@ -143,241 +124,233 @@ bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
#endif // OS_WIN
}
-bool Display::IsValidSurface(EGLSurface surface) {
- return (surface != NULL) && (surface == surface_.get());
+EGLBoolean Display::GetConfigAttrib(ThreadState* ts,
+ EGLConfig cfg,
+ EGLint attribute,
+ EGLint* value) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ const egl::Config* config = GetConfig(cfg);
+ if (!config)
+ return ts->ReturnError(EGL_BAD_CONFIG, EGL_FALSE);
+ if (!config->GetAttrib(attribute, value))
+ return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+EGLSurface Display::CreatePbufferSurface(ThreadState* ts,
+ EGLConfig cfg,
+ const EGLint* attrib_list) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
+ const egl::Config* config = GetConfig(cfg);
+ if (!config)
+ return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
+ EGLint value = EGL_NONE;
+ config->GetAttrib(EGL_SURFACE_TYPE, &value);
+ if ((value & EGL_PBUFFER_BIT) == 0)
+ return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ if (!egl::Surface::ValidatePbufferAttributeList(attrib_list))
+ return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+
+ int width = 1;
+ int height = 1;
+ if (attrib_list) {
+ for (const int32_t* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
+ switch (attr[0]) {
+ case EGL_WIDTH:
+ width = attr[1];
+ break;
+ case EGL_HEIGHT:
+ height = attr[1];
+ break;
+ }
+ }
+ }
+ return DoCreatePbufferSurface(ts, config, width, height);
+}
+
+EGLSurface Display::DoCreatePbufferSurface(ThreadState* ts,
+ const Config* config,
+ EGLint width,
+ EGLint height) {
+ lock_.AssertAcquired();
+ scoped_refptr<gfx::GLSurface> gl_surface;
+ gl_surface =
+ gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(width, height));
+ if (!gl_surface)
+ return ts->ReturnError(EGL_BAD_ALLOC, nullptr);
+ surfaces_.emplace_back(new Surface(gl_surface.get(), config));
+ return ts->ReturnSuccess<EGLSurface>(surfaces_.back().get());
}
-EGLSurface Display::CreateWindowSurface(EGLConfig config,
+EGLSurface Display::CreateWindowSurface(ThreadState* ts,
+ EGLConfig cfg,
EGLNativeWindowType win,
const EGLint* attrib_list) {
- if (surface_ != NULL) {
- // We do not support more than one window surface.
- return EGL_NO_SURFACE;
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
+ const egl::Config* config = GetConfig(cfg);
+ if (!config)
+ return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
+ EGLint value = EGL_NONE;
+ config->GetAttrib(EGL_SURFACE_TYPE, &value);
+ if ((value & EGL_WINDOW_BIT) == 0)
+ return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
+ if (!next_create_window_surface_creates_pbuffer_ && !IsValidNativeWindow(win))
+ return ts->ReturnError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ if (!Surface::ValidateWindowAttributeList(attrib_list))
+ return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ if (next_create_window_surface_creates_pbuffer_) {
+ EGLSurface result = DoCreatePbufferSurface(ts, config,
+ window_surface_pbuffer_width_,
+ window_surface_pbuffer_height_);
+ next_create_window_surface_creates_pbuffer_ = false;
+ window_surface_pbuffer_width_ = 0;
+ window_surface_pbuffer_height_ = 0;
+ return result;
}
-
- {
- gpu::TransferBufferManager* manager =
- new gpu::TransferBufferManager(nullptr);
- transfer_buffer_manager_ = manager;
- manager->Initialize();
- }
- std::unique_ptr<gpu::CommandBufferService> command_buffer(
- new gpu::CommandBufferService(transfer_buffer_manager_.get()));
-
- scoped_refptr<gpu::gles2::FeatureInfo> feature_info(
- new gpu::gles2::FeatureInfo(gpu_driver_bug_workarounds_));
- scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
- gpu_preferences_, NULL, NULL,
- new gpu::gles2::ShaderTranslatorCache(gpu_preferences_),
- new gpu::gles2::FramebufferCompletenessCache, feature_info, true));
-
- decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
- if (!decoder_.get())
- return EGL_NO_SURFACE;
-
- executor_.reset(
- new gpu::CommandExecutor(command_buffer.get(), decoder_.get(), NULL));
-
- decoder_->set_engine(executor_.get());
- gfx::Size size(create_offscreen_width_, create_offscreen_height_);
- if (create_offscreen_) {
- gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
- create_offscreen_ = false;
- create_offscreen_width_ = 0;
- create_offscreen_height_ = 0;
- } else {
- gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win);
- }
- if (!gl_surface_.get())
- return EGL_NO_SURFACE;
-
- gl_context_ = gfx::GLContext::CreateGLContext(NULL,
- gl_surface_.get(),
- gfx::PreferDiscreteGpu);
- if (!gl_context_.get())
- return EGL_NO_SURFACE;
-
- gl_context_->MakeCurrent(gl_surface_.get());
-
- EGLint depth_size = 0;
- EGLint alpha_size = 0;
- EGLint stencil_size = 0;
- GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size);
- GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size);
- GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size);
- std::vector<int32_t> attribs;
- attribs.push_back(EGL_DEPTH_SIZE);
- attribs.push_back(depth_size);
- attribs.push_back(EGL_ALPHA_SIZE);
- attribs.push_back(alpha_size);
- attribs.push_back(EGL_STENCIL_SIZE);
- attribs.push_back(stencil_size);
- // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null
- attribs.push_back(EGL_NONE);
-
- if (!decoder_->Initialize(gl_surface_.get(),
- gl_context_.get(),
- gl_surface_->IsOffscreen(),
- size,
- gpu::gles2::DisallowedFeatures(),
- attribs)) {
- return EGL_NO_SURFACE;
+ scoped_refptr<gfx::GLSurface> gl_surface;
+ gl_surface = gfx::GLSurface::CreateViewGLSurface(win);
+ if (!gl_surface)
+ return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ surfaces_.emplace_back(new Surface(gl_surface.get(), config));
+ return ts->ReturnSuccess(surfaces_.back().get());
+}
+
+EGLBoolean Display::DestroySurface(ThreadState* ts, EGLSurface sfe) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ auto it = std::find(surfaces_.begin(), surfaces_.end(), sfe);
+ if (it == surfaces_.end())
+ return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
+ surfaces_.erase(it);
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+EGLBoolean Display::ReleaseCurrent(ThreadState* ts) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnSuccess(EGL_TRUE);
+ ThreadState::AutoCurrentContextRestore accr(ts);
+ if (ts->current_context()) {
+ Context::MakeCurrent(ts->current_context(), ts->current_surface(), nullptr,
+ nullptr);
+ accr.SetCurrent(nullptr, nullptr);
}
-
- command_buffer->SetPutOffsetChangeCallback(base::Bind(
- &gpu::CommandExecutor::PutChanged, base::Unretained(executor_.get())));
- command_buffer->SetGetBufferChangeCallback(base::Bind(
- &gpu::CommandExecutor::SetGetBuffer, base::Unretained(executor_.get())));
-
- std::unique_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper(
- new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
- if (!cmd_helper->Initialize(kCommandBufferSize))
- return NULL;
-
- std::unique_ptr<gpu::TransferBuffer> transfer_buffer(
- new gpu::TransferBuffer(cmd_helper.get()));
-
- command_buffer_.reset(command_buffer.release());
- transfer_buffer_.reset(transfer_buffer.release());
- gles2_cmd_helper_.reset(cmd_helper.release());
- surface_.reset(new Surface(win));
-
- return surface_.get();
-}
-
-void Display::DestroySurface(EGLSurface surface) {
- DCHECK(IsValidSurface(surface));
- executor_.reset();
- if (decoder_.get()) {
- decoder_->Destroy(true);
- }
- decoder_.reset();
- gl_surface_ = NULL;
- gl_context_ = NULL;
- surface_.reset();
-}
-
-void Display::SwapBuffers(EGLSurface surface) {
- DCHECK(IsValidSurface(surface));
- context_->SwapBuffers();
-}
-
-bool Display::IsValidContext(EGLContext ctx) {
- return (ctx != NULL) && (ctx == context_.get());
-}
-
-EGLContext Display::CreateContext(EGLConfig config,
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+EGLBoolean Display::MakeCurrent(ThreadState* ts,
+ EGLSurface draw,
+ EGLSurface read,
+ EGLSurface ctx) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ ThreadState::AutoCurrentContextRestore accr(ts);
+ // Client might have called use because it changed some other gl binding
+ // global state. For example, the client might have called eglMakeCurrent on
+ // the same EGL as what command buffer uses. The client probably knows that
+ // this invalidates the internal state of command buffer, too. So reset the
+ // current context with accr in any case, regardless whether context or
+ // surface pointer changes.
+ Surface* new_surface = GetSurface(draw);
+ if (!new_surface)
+ return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
+ new_surface = GetSurface(read);
+ if (!new_surface)
+ return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
+ egl::Context* new_context = GetContext(ctx);
+ if (!new_context)
+ return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
+ if (draw != read)
+ return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
+
+ Surface* current_surface = ts->current_surface();
+ Context* current_context = ts->current_context();
+
+ if (current_context != new_context &&
+ new_context->is_current_in_some_thread())
+ return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
+
+ if (current_surface != new_surface &&
+ new_surface->is_current_in_some_thread())
+ return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
+
+ if (!Context::MakeCurrent(current_context,
+ current_context ? current_surface : nullptr,
+ new_context, new_context ? new_surface : nullptr))
+ return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
+
+ accr.SetCurrent(new_surface, new_context);
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+EGLBoolean Display::SwapBuffers(ThreadState* ts, EGLSurface sfe) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ egl::Surface* surface = GetSurface(sfe);
+ if (!surface)
+ return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (ts->current_surface() != surface)
+ return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!ts->current_context()->SwapBuffers(surface))
+ ts->ReturnError(EGL_CONTEXT_LOST, EGL_FALSE);
+ return ts->ReturnSuccess(EGL_TRUE);
+}
+
+EGLContext Display::CreateContext(ThreadState* ts,
+ EGLConfig cfg,
EGLContext share_ctx,
const EGLint* attrib_list) {
- DCHECK(IsValidConfig(config));
- // TODO(alokp): Add support for shared contexts.
- if (share_ctx != NULL)
- return EGL_NO_CONTEXT;
-
- DCHECK(command_buffer_ != NULL);
- DCHECK(transfer_buffer_.get());
-
- bool bind_generates_resources = true;
- bool lose_context_when_out_of_memory = false;
- bool support_client_side_arrays = true;
-
- context_.reset(
- new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(),
- NULL,
- transfer_buffer_.get(),
- bind_generates_resources,
- lose_context_when_out_of_memory,
- support_client_side_arrays,
- this));
-
- if (!context_->Initialize(kTransferBufferSize, kTransferBufferSize / 2,
- kTransferBufferSize * 2,
- gpu::SharedMemoryLimits::kNoLimit)) {
- return EGL_NO_CONTEXT;
- }
-
- context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
- context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
-
- return context_.get();
-}
-
-void Display::DestroyContext(EGLContext ctx) {
- DCHECK(IsValidContext(ctx));
- context_.reset();
- transfer_buffer_.reset();
-}
-
-bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
- if (ctx == EGL_NO_CONTEXT) {
- gles2::SetGLContext(NULL);
- } else {
- DCHECK(IsValidSurface(draw));
- DCHECK(IsValidSurface(read));
- DCHECK(IsValidContext(ctx));
- gles2::SetGLContext(context_.get());
- gl_context_->MakeCurrent(gl_surface_.get());
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_CONTEXT);
+ if (share_ctx != EGL_NO_CONTEXT) {
+ egl::Context* share_context = GetContext(share_ctx);
+ if (!share_context)
+ return ts->ReturnError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+ // TODO(alokp): Add support for shared contexts.
+ return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_CONTEXT);
}
- return true;
-}
-
-void Display::SetGpuControlClient(gpu::GpuControlClient*) {
- // The client is not currently called, so don't store it.
-}
-
-gpu::Capabilities Display::GetCapabilities() {
- return decoder_->GetCapabilities();
-}
-
-int32_t Display::CreateImage(ClientBuffer buffer,
- size_t width,
- size_t height,
- unsigned internalformat) {
- NOTIMPLEMENTED();
- return -1;
-}
-
-void Display::DestroyImage(int32_t id) {
- NOTIMPLEMENTED();
-}
-
-int32_t Display::CreateGpuMemoryBufferImage(size_t width,
- size_t height,
- unsigned internalformat,
- unsigned usage) {
- NOTIMPLEMENTED();
- return -1;
-}
-
-void Display::SignalQuery(uint32_t query, const base::Closure& callback) {
- NOTIMPLEMENTED();
-}
-void Display::SetLock(base::Lock*) {
- NOTIMPLEMENTED();
-}
-
-void Display::EnsureWorkVisible() {
- // This is only relevant for out-of-process command buffers.
-}
-
-gpu::CommandBufferNamespace Display::GetNamespaceID() const {
- return gpu::CommandBufferNamespace::IN_PROCESS;
-}
-
-gpu::CommandBufferId Display::GetCommandBufferID() const {
- return gpu::CommandBufferId();
-}
-
-int32_t Display::GetExtraCommandBufferData() const {
- return 0;
+ if (!egl::Context::ValidateAttributeList(attrib_list))
+ return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ const egl::Config* config = GetConfig(cfg);
+ if (!config)
+ return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ scoped_refptr<Context> context(new Context(this, config));
+ if (!context)
+ return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+ contexts_.emplace_back(context.get());
+ return ts->ReturnSuccess<EGLContext>(context.get());
+}
+
+EGLBoolean Display::DestroyContext(ThreadState* ts, EGLContext ctx) {
+ base::AutoLock auto_lock(lock_);
+ if (!is_initialized_)
+ return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ auto it = std::find(contexts_.begin(), contexts_.end(), ctx);
+ if (it == contexts_.end())
+ return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
+ (*it)->MarkDestroyed();
+ contexts_.erase(it);
+ return ts->ReturnSuccess(EGL_TRUE);
}
uint64_t Display::GenerateFenceSyncRelease() {
+ base::AutoLock auto_lock(lock_);
return next_fence_sync_release_++;
}
bool Display::IsFenceSyncRelease(uint64_t release) {
+ base::AutoLock auto_lock(lock_);
return release > 0 && release < next_fence_sync_release_;
}
@@ -389,13 +362,41 @@ bool Display::IsFenceSyncFlushReceived(uint64_t release) {
return IsFenceSyncRelease(release);
}
-void Display::SignalSyncToken(const gpu::SyncToken& sync_token,
- const base::Closure& callback) {
- NOTIMPLEMENTED();
+void Display::InitializeConfigsIfNeeded() {
+ lock_.AssertAcquired();
+ if (!configs_[0]) {
+ // The interface offers separate configs for window and pbuffer.
+ // This way we can record the client intention at context creation time.
+ // The GL implementation (gfx::GLContext and gfx::GLSurface) needs this
+ // distinction when creating a context.
+ configs_[0].reset(new Config(EGL_WINDOW_BIT));
+ configs_[1].reset(new Config(EGL_PBUFFER_BIT));
+ }
+}
+
+const Config* Display::GetConfig(EGLConfig cfg) {
+ lock_.AssertAcquired();
+ for (const auto& config : configs_) {
+ if (config.get() == cfg)
+ return config.get();
+ }
+ return nullptr;
+}
+
+Surface* Display::GetSurface(EGLSurface surface) {
+ lock_.AssertAcquired();
+ auto it = std::find(surfaces_.begin(), surfaces_.end(), surface);
+ if (it == surfaces_.end())
+ return nullptr;
+ return it->get();
}
-bool Display::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) {
- return false;
+Context* Display::GetContext(EGLContext context) {
+ lock_.AssertAcquired();
+ auto it = std::find(contexts_.begin(), contexts_.end(), context);
+ if (it == contexts_.end())
+ return nullptr;
+ return it->get();
}
} // namespace egl
« no previous file with comments | « gpu/gles2_conform_support/egl/display.h ('k') | gpu/gles2_conform_support/egl/egl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698