Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / gpu / gles2_conform_support / egl / display.cc
blob546184d1a7f3a18fbe98c8a8a7d8f5a070edf9f4
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "gpu/gles2_conform_support/egl/display.h"
7 #include <vector>
8 #include "base/at_exit.h"
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "gpu/command_buffer/client/gles2_implementation.h"
12 #include "gpu/command_buffer/client/gles2_lib.h"
13 #include "gpu/command_buffer/client/transfer_buffer.h"
14 #include "gpu/command_buffer/common/value_state.h"
15 #include "gpu/command_buffer/service/context_group.h"
16 #include "gpu/command_buffer/service/mailbox_manager.h"
17 #include "gpu/command_buffer/service/memory_tracking.h"
18 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
19 #include "gpu/command_buffer/service/valuebuffer_manager.h"
20 #include "gpu/gles2_conform_support/egl/config.h"
21 #include "gpu/gles2_conform_support/egl/surface.h"
23 namespace {
24 const int32 kCommandBufferSize = 1024 * 1024;
25 const int32 kTransferBufferSize = 512 * 1024;
28 namespace egl {
30 Display::Display(EGLNativeDisplayType display_id)
31 : display_id_(display_id),
32 is_initialized_(false),
33 #if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
34 exit_manager_(new base::AtExitManager),
35 #endif
36 create_offscreen_(false),
37 create_offscreen_width_(0),
38 create_offscreen_height_(0) {
41 Display::~Display() {
42 gles2::Terminate();
45 bool Display::Initialize() {
46 gles2::Initialize();
47 is_initialized_ = true;
48 return true;
51 bool Display::IsValidConfig(EGLConfig config) {
52 return (config != NULL) && (config == config_.get());
55 bool Display::ChooseConfigs(EGLConfig* configs,
56 EGLint config_size,
57 EGLint* num_config) {
58 // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
59 // does not support finding or choosing configs.
60 *num_config = 1;
61 if (configs != NULL) {
62 if (config_ == NULL) {
63 config_.reset(new Config);
65 configs[0] = config_.get();
67 return true;
70 bool Display::GetConfigs(EGLConfig* configs,
71 EGLint config_size,
72 EGLint* num_config) {
73 // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
74 // does not support finding or choosing configs.
75 *num_config = 1;
76 if (configs != NULL) {
77 if (config_ == NULL) {
78 config_.reset(new Config);
80 configs[0] = config_.get();
82 return true;
85 bool Display::GetConfigAttrib(EGLConfig config,
86 EGLint attribute,
87 EGLint* value) {
88 const egl::Config* cfg = static_cast<egl::Config*>(config);
89 return cfg->GetAttrib(attribute, value);
92 bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
93 #if defined OS_WIN
94 return ::IsWindow(win) != FALSE;
95 #else
96 // TODO(alokp): Validate window handle.
97 return true;
98 #endif // OS_WIN
101 bool Display::IsValidSurface(EGLSurface surface) {
102 return (surface != NULL) && (surface == surface_.get());
105 EGLSurface Display::CreateWindowSurface(EGLConfig config,
106 EGLNativeWindowType win,
107 const EGLint* attrib_list) {
108 if (surface_ != NULL) {
109 // We do not support more than one window surface.
110 return EGL_NO_SURFACE;
114 gpu::TransferBufferManager* manager =
115 new gpu::TransferBufferManager(nullptr);
116 transfer_buffer_manager_ = manager;
117 manager->Initialize();
119 scoped_ptr<gpu::CommandBufferService> command_buffer(
120 new gpu::CommandBufferService(transfer_buffer_manager_.get()));
121 if (!command_buffer->Initialize())
122 return NULL;
124 scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
125 NULL, NULL, new gpu::gles2::ShaderTranslatorCache,
126 new gpu::gles2::FramebufferCompletenessCache, NULL, NULL, NULL, true));
128 decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
129 if (!decoder_.get())
130 return EGL_NO_SURFACE;
132 gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer.get(),
133 decoder_.get(),
134 NULL));
136 decoder_->set_engine(gpu_scheduler_.get());
137 gfx::Size size(create_offscreen_width_, create_offscreen_height_);
138 if (create_offscreen_) {
139 gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
140 create_offscreen_ = false;
141 create_offscreen_width_ = 0;
142 create_offscreen_height_ = 0;
143 } else {
144 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win);
146 if (!gl_surface_.get())
147 return EGL_NO_SURFACE;
149 gl_context_ = gfx::GLContext::CreateGLContext(NULL,
150 gl_surface_.get(),
151 gfx::PreferDiscreteGpu);
152 if (!gl_context_.get())
153 return EGL_NO_SURFACE;
155 gl_context_->MakeCurrent(gl_surface_.get());
157 EGLint depth_size = 0;
158 EGLint alpha_size = 0;
159 EGLint stencil_size = 0;
160 GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size);
161 GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size);
162 GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size);
163 std::vector<int32> attribs;
164 attribs.push_back(EGL_DEPTH_SIZE);
165 attribs.push_back(depth_size);
166 attribs.push_back(EGL_ALPHA_SIZE);
167 attribs.push_back(alpha_size);
168 attribs.push_back(EGL_STENCIL_SIZE);
169 attribs.push_back(stencil_size);
170 // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null
171 attribs.push_back(EGL_NONE);
173 if (!decoder_->Initialize(gl_surface_.get(),
174 gl_context_.get(),
175 gl_surface_->IsOffscreen(),
176 size,
177 gpu::gles2::DisallowedFeatures(),
178 attribs)) {
179 return EGL_NO_SURFACE;
182 command_buffer->SetPutOffsetChangeCallback(
183 base::Bind(&gpu::GpuScheduler::PutChanged,
184 base::Unretained(gpu_scheduler_.get())));
185 command_buffer->SetGetBufferChangeCallback(
186 base::Bind(&gpu::GpuScheduler::SetGetBuffer,
187 base::Unretained(gpu_scheduler_.get())));
189 scoped_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper(
190 new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
191 if (!cmd_helper->Initialize(kCommandBufferSize))
192 return NULL;
194 scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer(
195 cmd_helper.get()));
197 command_buffer_.reset(command_buffer.release());
198 transfer_buffer_.reset(transfer_buffer.release());
199 gles2_cmd_helper_.reset(cmd_helper.release());
200 surface_.reset(new Surface(win));
202 return surface_.get();
205 void Display::DestroySurface(EGLSurface surface) {
206 DCHECK(IsValidSurface(surface));
207 gpu_scheduler_.reset();
208 if (decoder_.get()) {
209 decoder_->Destroy(true);
211 decoder_.reset();
212 gl_surface_ = NULL;
213 gl_context_ = NULL;
214 surface_.reset();
217 void Display::SwapBuffers(EGLSurface surface) {
218 DCHECK(IsValidSurface(surface));
219 context_->SwapBuffers();
222 bool Display::IsValidContext(EGLContext ctx) {
223 return (ctx != NULL) && (ctx == context_.get());
226 EGLContext Display::CreateContext(EGLConfig config,
227 EGLContext share_ctx,
228 const EGLint* attrib_list) {
229 DCHECK(IsValidConfig(config));
230 // TODO(alokp): Add support for shared contexts.
231 if (share_ctx != NULL)
232 return EGL_NO_CONTEXT;
234 DCHECK(command_buffer_ != NULL);
235 DCHECK(transfer_buffer_.get());
237 bool bind_generates_resources = true;
238 bool lose_context_when_out_of_memory = false;
239 bool support_client_side_arrays = true;
241 context_.reset(
242 new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(),
243 NULL,
244 transfer_buffer_.get(),
245 bind_generates_resources,
246 lose_context_when_out_of_memory,
247 support_client_side_arrays,
248 this));
250 if (!context_->Initialize(
251 kTransferBufferSize,
252 kTransferBufferSize / 2,
253 kTransferBufferSize * 2,
254 gpu::gles2::GLES2Implementation::kNoLimit)) {
255 return EGL_NO_CONTEXT;
258 context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
259 context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
261 return context_.get();
264 void Display::DestroyContext(EGLContext ctx) {
265 DCHECK(IsValidContext(ctx));
266 context_.reset();
267 transfer_buffer_.reset();
270 bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
271 if (ctx == EGL_NO_CONTEXT) {
272 gles2::SetGLContext(NULL);
273 } else {
274 DCHECK(IsValidSurface(draw));
275 DCHECK(IsValidSurface(read));
276 DCHECK(IsValidContext(ctx));
277 gles2::SetGLContext(context_.get());
279 return true;
282 gpu::Capabilities Display::GetCapabilities() {
283 return decoder_->GetCapabilities();
286 int32_t Display::CreateImage(ClientBuffer buffer,
287 size_t width,
288 size_t height,
289 unsigned internalformat) {
290 NOTIMPLEMENTED();
291 return -1;
294 void Display::DestroyImage(int32 id) {
295 NOTIMPLEMENTED();
298 int32_t Display::CreateGpuMemoryBufferImage(size_t width,
299 size_t height,
300 unsigned internalformat,
301 unsigned usage) {
302 NOTIMPLEMENTED();
303 return -1;
306 uint32 Display::InsertSyncPoint() {
307 NOTIMPLEMENTED();
308 return 0u;
311 uint32 Display::InsertFutureSyncPoint() {
312 NOTIMPLEMENTED();
313 return 0u;
316 void Display::RetireSyncPoint(uint32 sync_point) {
317 NOTIMPLEMENTED();
320 void Display::SignalSyncPoint(uint32 sync_point,
321 const base::Closure& callback) {
322 NOTIMPLEMENTED();
325 void Display::SignalQuery(uint32 query, const base::Closure& callback) {
326 NOTIMPLEMENTED();
329 void Display::SetSurfaceVisible(bool visible) {
330 NOTIMPLEMENTED();
333 uint32 Display::CreateStreamTexture(uint32 texture_id) {
334 NOTIMPLEMENTED();
335 return 0;
338 void Display::SetLock(base::Lock*) {
339 NOTIMPLEMENTED();
342 bool Display::IsGpuChannelLost() {
343 NOTIMPLEMENTED();
344 return false;
347 gpu::CommandBufferNamespace Display::GetNamespaceID() const {
348 return gpu::CommandBufferNamespace::IN_PROCESS;
351 uint64_t Display::GetCommandBufferID() const {
352 return 0;
355 } // namespace egl