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

Side by Side Diff: ui/gl/gl_surface_ozone.cc

Issue 1285183008: Ozone integration. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: add missing license header Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gl/gl_surface_osmesa.cc ('k') | ui/gl/gl_surface_stub.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gl/gl_surface.h" 5 #include "ui/gl/gl_surface.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_vector.h"
12 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
13 #include "base/threading/worker_pool.h" 14 #include "base/threading/worker_pool.h"
14 #include "ui/gfx/native_widget_types.h" 15 #include "ui/gfx/native_widget_types.h"
15 #include "ui/gl/gl_context.h" 16 #include "ui/gl/gl_context.h"
16 #include "ui/gl/gl_image.h" 17 #include "ui/gl/gl_image.h"
17 #include "ui/gl/gl_image_linux_dma_buffer.h" 18 #include "ui/gl/gl_image_linux_dma_buffer.h"
18 #include "ui/gl/gl_implementation.h" 19 #include "ui/gl/gl_implementation.h"
19 #include "ui/gl/gl_surface_egl.h" 20 #include "ui/gl/gl_surface_egl.h"
20 #include "ui/gl/gl_surface_osmesa.h" 21 #include "ui/gl/gl_surface_osmesa.h"
21 #include "ui/gl/gl_surface_stub.h" 22 #include "ui/gl/gl_surface_stub.h"
22 #include "ui/gl/scoped_binders.h" 23 #include "ui/gl/scoped_binders.h"
23 #include "ui/gl/scoped_make_current.h" 24 #include "ui/gl/scoped_make_current.h"
24 #include "ui/ozone/public/native_pixmap.h" 25 #include "ui/ozone/public/native_pixmap.h"
26 #include "ui/ozone/public/ozone_platform.h"
25 #include "ui/ozone/public/surface_factory_ozone.h" 27 #include "ui/ozone/public/surface_factory_ozone.h"
26 #include "ui/ozone/public/surface_ozone_egl.h" 28 #include "ui/ozone/public/surface_ozone_egl.h"
27 29
28 namespace gfx { 30 namespace gfx {
29 31
30 namespace { 32 namespace {
31 33
32 void WaitForFence(EGLDisplay display, EGLSyncKHR fence) { 34 void WaitForFence(EGLDisplay display, EGLSyncKHR fence) {
33 eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 35 eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
34 EGL_FOREVER_KHR); 36 EGL_FOREVER_KHR);
35 } 37 }
36 38
37 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow 39 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow
38 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { 40 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL {
39 public: 41 public:
40 GLSurfaceOzoneEGL(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, 42 GLSurfaceOzoneEGL(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
41 AcceleratedWidget widget) 43 AcceleratedWidget widget,
42 : NativeViewGLSurfaceEGL(ozone_surface->GetNativeWindow()), 44 const gfx::SurfaceConfiguration& requested_configuration);
43 ozone_surface_(ozone_surface.Pass()),
44 widget_(widget) {}
45 45
46 bool Initialize() override { 46 // GLSurface:
47 return Initialize(ozone_surface_->CreateVSyncProvider()); 47 bool Initialize() override;
48 } 48 bool Resize(const gfx::Size& size) override;
49 bool Resize(const gfx::Size& size) override { 49 gfx::SwapResult SwapBuffers() override;
50 if (!ozone_surface_->ResizeNativeWindow(size)) {
51 if (!ReinitializeNativeSurface() ||
52 !ozone_surface_->ResizeNativeWindow(size))
53 return false;
54 }
55
56 return NativeViewGLSurfaceEGL::Resize(size);
57 }
58 bool SwapBuffers() override {
59 if (!NativeViewGLSurfaceEGL::SwapBuffers())
60 return false;
61
62 return ozone_surface_->OnSwapBuffers();
63 }
64 bool ScheduleOverlayPlane(int z_order, 50 bool ScheduleOverlayPlane(int z_order,
65 OverlayTransform transform, 51 OverlayTransform transform,
66 GLImage* image, 52 GLImage* image,
67 const Rect& bounds_rect, 53 const Rect& bounds_rect,
68 const RectF& crop_rect) override { 54 const RectF& crop_rect) override;
69 return image->ScheduleOverlayPlane(
70 widget_, z_order, transform, bounds_rect, crop_rect);
71 }
72 55
73 private: 56 private:
74 using NativeViewGLSurfaceEGL::Initialize; 57 using NativeViewGLSurfaceEGL::Initialize;
75 58
76 ~GLSurfaceOzoneEGL() override { 59 ~GLSurfaceOzoneEGL() override;
77 Destroy(); // EGL surface must be destroyed before SurfaceOzone
78 }
79 60
80 bool ReinitializeNativeSurface() { 61 bool ReinitializeNativeSurface();
81 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
82 GLContext* current_context = GLContext::GetCurrent();
83 bool was_current =
84 current_context && current_context->IsCurrent(this);
85 if (was_current) {
86 scoped_make_current.reset(
87 new ui::ScopedMakeCurrent(current_context, this));
88 }
89
90 Destroy();
91 ozone_surface_ =
92 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
93 widget_).Pass();
94 if (!ozone_surface_) {
95 LOG(ERROR) << "Failed to create native surface.";
96 return false;
97 }
98
99 window_ = ozone_surface_->GetNativeWindow();
100 if (!Initialize()) {
101 LOG(ERROR) << "Failed to initialize.";
102 return false;
103 }
104
105 return true;
106 }
107 62
108 // The native surface. Deleting this is allowed to free the EGLNativeWindow. 63 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
109 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; 64 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
110 AcceleratedWidget widget_; 65 AcceleratedWidget widget_;
111 66
112 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL); 67 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL);
113 }; 68 };
114 69
70 GLSurfaceOzoneEGL::GLSurfaceOzoneEGL(
71 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
72 AcceleratedWidget widget,
73 const gfx::SurfaceConfiguration& requested_configuration)
74 : NativeViewGLSurfaceEGL(ozone_surface->GetNativeWindow(),
75 requested_configuration),
76 ozone_surface_(ozone_surface.Pass()),
77 widget_(widget) {
78 }
79
80 bool GLSurfaceOzoneEGL::Initialize() {
81 return Initialize(ozone_surface_->CreateVSyncProvider());
82 }
83
84 bool GLSurfaceOzoneEGL::Resize(const gfx::Size& size) {
85 if (!ozone_surface_->ResizeNativeWindow(size)) {
86 if (!ReinitializeNativeSurface() ||
87 !ozone_surface_->ResizeNativeWindow(size))
88 return false;
89 }
90
91 return NativeViewGLSurfaceEGL::Resize(size);
92 }
93
94 gfx::SwapResult GLSurfaceOzoneEGL::SwapBuffers() {
95 gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers();
96 if (result != gfx::SwapResult::SWAP_ACK)
97 return result;
98
99 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
100 : gfx::SwapResult::SWAP_FAILED;
101 }
102
103 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order,
104 OverlayTransform transform,
105 GLImage* image,
106 const Rect& bounds_rect,
107 const RectF& crop_rect) {
108 return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect,
109 crop_rect);
110 }
111
112 GLSurfaceOzoneEGL::~GLSurfaceOzoneEGL() {
113 Destroy(); // EGL surface must be destroyed before SurfaceOzone
114 }
115
116 bool GLSurfaceOzoneEGL::ReinitializeNativeSurface() {
117 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
118 GLContext* current_context = GLContext::GetCurrent();
119 bool was_current = current_context && current_context->IsCurrent(this);
120 if (was_current) {
121 scoped_make_current.reset(new ui::ScopedMakeCurrent(current_context, this));
122 }
123
124 Destroy();
125 ozone_surface_ = ui::OzonePlatform::GetInstance()
126 ->GetSurfaceFactoryOzone()
127 ->CreateEGLSurfaceForWidget(widget_)
128 .Pass();
129 if (!ozone_surface_) {
130 LOG(ERROR) << "Failed to create native surface.";
131 return false;
132 }
133
134 window_ = ozone_surface_->GetNativeWindow();
135 if (!Initialize()) {
136 LOG(ERROR) << "Failed to initialize.";
137 return false;
138 }
139
140 return true;
141 }
142
115 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { 143 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
116 public: 144 public:
117 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, 145 GLSurfaceOzoneSurfaceless(
118 AcceleratedWidget widget) 146 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
119 : SurfacelessEGL(gfx::Size()), 147 AcceleratedWidget widget,
120 ozone_surface_(ozone_surface.Pass()), 148 const gfx::SurfaceConfiguration& requested_configuration);
121 widget_(widget), 149
122 has_implicit_external_sync_( 150 // GLSurface:
123 HasEGLExtension("EGL_ARM_implicit_external_sync")), 151 bool Initialize() override;
124 last_swap_buffers_result_(true), 152 bool Resize(const gfx::Size& size) override;
125 weak_factory_(this) {} 153 gfx::SwapResult SwapBuffers() override;
126
127 bool Initialize() override {
128 if (!SurfacelessEGL::Initialize())
129 return false;
130 vsync_provider_ = ozone_surface_->CreateVSyncProvider();
131 if (!vsync_provider_)
132 return false;
133 return true;
134 }
135 bool Resize(const gfx::Size& size) override {
136 if (!ozone_surface_->ResizeNativeWindow(size))
137 return false;
138
139 return SurfacelessEGL::Resize(size);
140 }
141 bool SwapBuffers() override {
142 glFlush();
143 // TODO: the following should be replaced by a per surface flush as it gets
144 // implemented in GL drivers.
145 if (has_implicit_external_sync_) {
146 EGLSyncKHR fence = InsertFence();
147 if (!fence)
148 return false;
149
150 EGLDisplay display = GetDisplay();
151 WaitForFence(display, fence);
152 eglDestroySyncKHR(display, fence);
153 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
154 glFinish();
155 }
156
157 return ozone_surface_->OnSwapBuffers();
158 }
159 bool ScheduleOverlayPlane(int z_order, 154 bool ScheduleOverlayPlane(int z_order,
160 OverlayTransform transform, 155 OverlayTransform transform,
161 GLImage* image, 156 GLImage* image,
162 const Rect& bounds_rect, 157 const Rect& bounds_rect,
163 const RectF& crop_rect) override { 158 const RectF& crop_rect) override;
164 return image->ScheduleOverlayPlane( 159 bool IsOffscreen() override;
165 widget_, z_order, transform, bounds_rect, crop_rect); 160 VSyncProvider* GetVSyncProvider() override;
166 } 161 bool SupportsPostSubBuffer() override;
167 bool IsOffscreen() override { return false; } 162 gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override;
168 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } 163 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override;
169 bool SupportsPostSubBuffer() override { return true; }
170 bool PostSubBuffer(int x, int y, int width, int height) override {
171 // The actual sub buffer handling is handled at higher layers.
172 SwapBuffers();
173 return true;
174 }
175 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override {
176 glFlush();
177 // TODO: the following should be replaced by a per surface flush as it gets
178 // implemented in GL drivers.
179 if (has_implicit_external_sync_) {
180 // If last swap failed, don't try to schedule new ones.
181 if (!last_swap_buffers_result_) {
182 last_swap_buffers_result_ = true;
183 return false;
184 }
185
186 EGLSyncKHR fence = InsertFence();
187 if (!fence)
188 return false;
189
190 base::Closure fence_wait_task =
191 base::Bind(&WaitForFence, GetDisplay(), fence);
192
193 base::Closure fence_retired_callback =
194 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
195 weak_factory_.GetWeakPtr(), fence, callback);
196
197 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
198 fence_retired_callback, false);
199 return true;
200 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
201 glFinish();
202 }
203 return ozone_surface_->OnSwapBuffersAsync(callback);
204 }
205 bool PostSubBufferAsync(int x, 164 bool PostSubBufferAsync(int x,
206 int y, 165 int y,
207 int width, 166 int width,
208 int height, 167 int height,
209 const SwapCompletionCallback& callback) override { 168 const SwapCompletionCallback& callback) override;
210 return SwapBuffersAsync(callback);
211 }
212 169
213 protected: 170 protected:
214 ~GLSurfaceOzoneSurfaceless() override { 171 struct Overlay {
215 Destroy(); // EGL surface must be destroyed before SurfaceOzone 172 Overlay(int z_order,
216 } 173 OverlayTransform transform,
217 174 GLImage* image,
218 EGLSyncKHR InsertFence() { 175 const Rect& bounds_rect,
219 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, 176 const RectF& crop_rect);
220 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, 177
221 EGL_NONE}; 178 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget) const;
222 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); 179
223 } 180 int z_order;
224 181 OverlayTransform transform;
225 void FenceRetired(EGLSyncKHR fence, const SwapCompletionCallback& callback) { 182 scoped_refptr<GLImage> image;
226 eglDestroySyncKHR(GetDisplay(), fence); 183 Rect bounds_rect;
227 last_swap_buffers_result_ = ozone_surface_->OnSwapBuffersAsync(callback); 184 RectF crop_rect;
228 } 185 };
186
187 struct PendingFrame {
188 PendingFrame();
189
190 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget);
191
192 bool ready;
193 std::vector<Overlay> overlays;
194 SwapCompletionCallback callback;
195 };
196
197 ~GLSurfaceOzoneSurfaceless() override;
198
199 void SubmitFrame();
200
201 EGLSyncKHR InsertFence();
202 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame);
203
204 void SwapCompleted(const SwapCompletionCallback& callback,
205 gfx::SwapResult result);
229 206
230 // The native surface. Deleting this is allowed to free the EGLNativeWindow. 207 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
231 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; 208 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
232 AcceleratedWidget widget_; 209 AcceleratedWidget widget_;
233 scoped_ptr<VSyncProvider> vsync_provider_; 210 scoped_ptr<VSyncProvider> vsync_provider_;
211 ScopedVector<PendingFrame> unsubmitted_frames_;
234 bool has_implicit_external_sync_; 212 bool has_implicit_external_sync_;
235 bool last_swap_buffers_result_; 213 bool last_swap_buffers_result_;
214 bool swap_buffers_pending_;
236 215
237 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; 216 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_;
238 217
239 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); 218 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
240 }; 219 };
241 220
221 GLSurfaceOzoneSurfaceless::Overlay::Overlay(int z_order,
222 OverlayTransform transform,
223 GLImage* image,
224 const Rect& bounds_rect,
225 const RectF& crop_rect)
226 : z_order(z_order),
227 transform(transform),
228 image(image),
229 bounds_rect(bounds_rect),
230 crop_rect(crop_rect) {
231 }
232
233 bool GLSurfaceOzoneSurfaceless::Overlay::ScheduleOverlayPlane(
234 gfx::AcceleratedWidget widget) const {
235 return image->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect,
236 crop_rect);
237 }
238
239 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {
240 }
241
242 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes(
243 gfx::AcceleratedWidget widget) {
244 for (const auto& overlay : overlays)
245 if (!overlay.ScheduleOverlayPlane(widget))
246 return false;
247 return true;
248 }
249
250 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless(
251 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
252 AcceleratedWidget widget,
253 const gfx::SurfaceConfiguration& requested_configuration)
254 : SurfacelessEGL(gfx::Size(), requested_configuration),
255 ozone_surface_(ozone_surface.Pass()),
256 widget_(widget),
257 has_implicit_external_sync_(
258 HasEGLExtension("EGL_ARM_implicit_external_sync")),
259 last_swap_buffers_result_(true),
260 swap_buffers_pending_(false),
261 weak_factory_(this) {
262 unsubmitted_frames_.push_back(new PendingFrame());
263 }
264
265 bool GLSurfaceOzoneSurfaceless::Initialize() {
266 if (!SurfacelessEGL::Initialize())
267 return false;
268 vsync_provider_ = ozone_surface_->CreateVSyncProvider();
269 if (!vsync_provider_)
270 return false;
271 return true;
272 }
273 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size) {
274 if (!ozone_surface_->ResizeNativeWindow(size))
275 return false;
276
277 return SurfacelessEGL::Resize(size);
278 }
279 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() {
280 glFlush();
281 // TODO: the following should be replaced by a per surface flush as it gets
282 // implemented in GL drivers.
283 if (has_implicit_external_sync_) {
284 EGLSyncKHR fence = InsertFence();
285 if (!fence)
286 return SwapResult::SWAP_FAILED;
287
288 EGLDisplay display = GetDisplay();
289 WaitForFence(display, fence);
290 eglDestroySyncKHR(display, fence);
291 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
292 glFinish();
293 }
294
295 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_);
296 unsubmitted_frames_.back()->overlays.clear();
297
298 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
299 : gfx::SwapResult::SWAP_FAILED;
300 }
301 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(int z_order,
302 OverlayTransform transform,
303 GLImage* image,
304 const Rect& bounds_rect,
305 const RectF& crop_rect) {
306 unsubmitted_frames_.back()->overlays.push_back(
307 Overlay(z_order, transform, image, bounds_rect, crop_rect));
308 return true;
309 }
310 bool GLSurfaceOzoneSurfaceless::IsOffscreen() {
311 return false;
312 }
313 VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() {
314 return vsync_provider_.get();
315 }
316 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() {
317 return true;
318 }
319 gfx::SwapResult GLSurfaceOzoneSurfaceless::PostSubBuffer(int x,
320 int y,
321 int width,
322 int height) {
323 // The actual sub buffer handling is handled at higher layers.
324 SwapBuffers();
325 return gfx::SwapResult::SWAP_ACK;
326 }
327 bool GLSurfaceOzoneSurfaceless::SwapBuffersAsync(
328 const SwapCompletionCallback& callback) {
329 // If last swap failed, don't try to schedule new ones.
330 if (!last_swap_buffers_result_)
331 return false;
332
333 glFlush();
334
335 SwapCompletionCallback surface_swap_callback =
336 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted,
337 weak_factory_.GetWeakPtr(), callback);
338
339 PendingFrame* frame = unsubmitted_frames_.back();
340 frame->callback = surface_swap_callback;
341 unsubmitted_frames_.push_back(new PendingFrame());
342
343 // TODO: the following should be replaced by a per surface flush as it gets
344 // implemented in GL drivers.
345 if (has_implicit_external_sync_) {
346 EGLSyncKHR fence = InsertFence();
347 if (!fence)
348 return false;
349
350 base::Closure fence_wait_task =
351 base::Bind(&WaitForFence, GetDisplay(), fence);
352
353 base::Closure fence_retired_callback =
354 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
355 weak_factory_.GetWeakPtr(), fence, frame);
356
357 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
358 fence_retired_callback, false);
359 return true;
360 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
361 glFinish();
362 }
363
364 frame->ready = true;
365 SubmitFrame();
366 return last_swap_buffers_result_;
367 }
368 bool GLSurfaceOzoneSurfaceless::PostSubBufferAsync(
369 int x,
370 int y,
371 int width,
372 int height,
373 const SwapCompletionCallback& callback) {
374 return SwapBuffersAsync(callback);
375 }
376
377 GLSurfaceOzoneSurfaceless::~GLSurfaceOzoneSurfaceless() {
378 Destroy(); // EGL surface must be destroyed before SurfaceOzone
379 }
380
381 void GLSurfaceOzoneSurfaceless::SubmitFrame() {
382 DCHECK(!unsubmitted_frames_.empty());
383
384 if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) {
385 scoped_ptr<PendingFrame> frame(unsubmitted_frames_.front());
386 unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin());
387 swap_buffers_pending_ = true;
388
389 last_swap_buffers_result_ =
390 frame->ScheduleOverlayPlanes(widget_) &&
391 ozone_surface_->OnSwapBuffersAsync(frame->callback);
392 }
393 }
394
395 EGLSyncKHR GLSurfaceOzoneSurfaceless::InsertFence() {
396 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR,
397 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM,
398 EGL_NONE};
399 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
400 }
401
402 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence,
403 PendingFrame* frame) {
404 eglDestroySyncKHR(GetDisplay(), fence);
405 frame->ready = true;
406 SubmitFrame();
407 }
408
409 void GLSurfaceOzoneSurfaceless::SwapCompleted(
410 const SwapCompletionCallback& callback,
411 gfx::SwapResult result) {
412 callback.Run(result);
413 swap_buffers_pending_ = false;
414
415 SubmitFrame();
416 }
417
242 // This provides surface-like semantics implemented through surfaceless. 418 // This provides surface-like semantics implemented through surfaceless.
243 // A framebuffer is bound automatically. 419 // A framebuffer is bound automatically.
244 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl 420 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
245 : public GLSurfaceOzoneSurfaceless { 421 : public GLSurfaceOzoneSurfaceless {
246 public: 422 public:
247 GLSurfaceOzoneSurfacelessSurfaceImpl( 423 GLSurfaceOzoneSurfacelessSurfaceImpl(
248 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, 424 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
249 AcceleratedWidget widget) 425 AcceleratedWidget widget,
250 : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget), 426 const gfx::SurfaceConfiguration& requested_configuration);
251 fbo_(0), 427
252 current_surface_(0) { 428 // GLSurface:
253 for (auto& texture : textures_) 429 unsigned int GetBackingFrameBufferObject() override;
254 texture = 0; 430 bool OnMakeCurrent(GLContext* context) override;
255 } 431 bool Resize(const gfx::Size& size) override;
256 432 bool SupportsPostSubBuffer() override;
257 unsigned int GetBackingFrameBufferObject() override { return fbo_; } 433 gfx::SwapResult SwapBuffers() override;
258 434 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override;
259 bool OnMakeCurrent(GLContext* context) override { 435 void Destroy() override;
260 if (!fbo_) {
261 glGenFramebuffersEXT(1, &fbo_);
262 if (!fbo_)
263 return false;
264 glGenTextures(arraysize(textures_), textures_);
265 if (!CreatePixmaps())
266 return false;
267 }
268 BindFramebuffer();
269 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
270 return SurfacelessEGL::OnMakeCurrent(context);
271 }
272
273 bool Resize(const gfx::Size& size) override {
274 if (size == GetSize())
275 return true;
276 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps();
277 }
278
279 bool SupportsPostSubBuffer() override { return false; }
280
281 bool SwapBuffers() override {
282 if (!images_[current_surface_]->ScheduleOverlayPlane(
283 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
284 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
285 return false;
286 if (!GLSurfaceOzoneSurfaceless::SwapBuffers())
287 return false;
288 current_surface_ ^= 1;
289 BindFramebuffer();
290 return true;
291 }
292
293 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override {
294 if (!images_[current_surface_]->ScheduleOverlayPlane(
295 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
296 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
297 return false;
298 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback))
299 return false;
300 current_surface_ ^= 1;
301 BindFramebuffer();
302 return true;
303 }
304
305 void Destroy() override {
306 GLContext* current_context = GLContext::GetCurrent();
307 DCHECK(current_context && current_context->IsCurrent(this));
308 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
309 if (fbo_) {
310 glDeleteTextures(arraysize(textures_), textures_);
311 for (auto& texture : textures_)
312 texture = 0;
313 glDeleteFramebuffersEXT(1, &fbo_);
314 fbo_ = 0;
315 }
316 for (auto image : images_) {
317 if (image)
318 image->Destroy(true);
319 }
320 }
321 436
322 private: 437 private:
323 class SurfaceImage : public GLImageLinuxDMABuffer { 438 class SurfaceImage : public GLImageLinuxDMABuffer {
324 public: 439 public:
325 SurfaceImage(const gfx::Size& size, unsigned internalformat) 440 SurfaceImage(const gfx::Size& size, unsigned internalformat);
326 : GLImageLinuxDMABuffer(size, internalformat) {}
327 441
328 bool Initialize(scoped_refptr<ui::NativePixmap> pixmap, 442 bool Initialize(scoped_refptr<ui::NativePixmap> pixmap,
329 gfx::GpuMemoryBuffer::Format format) { 443 gfx::GpuMemoryBuffer::Format format);
330 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false);
331 if (!GLImageLinuxDMABuffer::Initialize(handle, format,
332 pixmap->GetDmaBufPitch()))
333 return false;
334 pixmap_ = pixmap;
335 return true;
336 }
337 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 444 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
338 int z_order, 445 int z_order,
339 gfx::OverlayTransform transform, 446 gfx::OverlayTransform transform,
340 const gfx::Rect& bounds_rect, 447 const gfx::Rect& bounds_rect,
341 const gfx::RectF& crop_rect) override { 448 const gfx::RectF& crop_rect) override;
342 return ui::SurfaceFactoryOzone::GetInstance()->ScheduleOverlayPlane(
343 widget, z_order, transform, pixmap_, bounds_rect, crop_rect);
344 }
345 449
346 private: 450 private:
347 ~SurfaceImage() override {} 451 ~SurfaceImage() override;
348 452
349 scoped_refptr<ui::NativePixmap> pixmap_; 453 scoped_refptr<ui::NativePixmap> pixmap_;
350 }; 454 };
351 455
352 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override { 456 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override;
353 DCHECK(!fbo_); 457
354 for (size_t i = 0; i < arraysize(textures_); i++) 458 void BindFramebuffer();
355 DCHECK(!textures_[i]) << "texture " << i << " not released"; 459 bool CreatePixmaps();
356 }
357
358 void BindFramebuffer() {
359 ScopedFrameBufferBinder fb(fbo_);
360 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
361 GL_TEXTURE_2D, textures_[current_surface_], 0);
362 }
363
364 bool CreatePixmaps() {
365 if (!fbo_)
366 return true;
367 for (size_t i = 0; i < arraysize(textures_); i++) {
368 scoped_refptr<ui::NativePixmap> pixmap =
369 ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap(
370 widget_, GetSize(), ui::SurfaceFactoryOzone::RGBA_8888,
371 ui::SurfaceFactoryOzone::SCANOUT);
372 if (!pixmap)
373 return false;
374 scoped_refptr<SurfaceImage> image = new SurfaceImage(GetSize(), GL_RGBA);
375 if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888))
376 return false;
377 images_[i] = image;
378 // Bind image to texture.
379 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]);
380 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
381 return false;
382 }
383 return true;
384 }
385 460
386 GLuint fbo_; 461 GLuint fbo_;
387 GLuint textures_[2]; 462 GLuint textures_[2];
388 scoped_refptr<GLImage> images_[2]; 463 scoped_refptr<GLImage> images_[2];
389 int current_surface_; 464 int current_surface_;
390 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl); 465 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl);
391 }; 466 };
392 467
468 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::SurfaceImage(
469 const gfx::Size& size,
470 unsigned internalformat)
471 : GLImageLinuxDMABuffer(size, internalformat) {
472 }
473
474 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::Initialize(
475 scoped_refptr<ui::NativePixmap> pixmap,
476 gfx::GpuMemoryBuffer::Format format) {
477 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false);
478 if (!GLImageLinuxDMABuffer::Initialize(handle, format,
479 pixmap->GetDmaBufPitch()))
480 return false;
481 pixmap_ = pixmap;
482 return true;
483 }
484 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::ScheduleOverlayPlane(
485 gfx::AcceleratedWidget widget,
486 int z_order,
487 gfx::OverlayTransform transform,
488 const gfx::Rect& bounds_rect,
489 const gfx::RectF& crop_rect) {
490 return pixmap_->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect,
491 crop_rect);
492 }
493
494 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::~SurfaceImage() {
495 }
496
497 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl(
498 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
499 AcceleratedWidget widget,
500 const gfx::SurfaceConfiguration& requested_configuration)
501 : GLSurfaceOzoneSurfaceless(
502 ozone_surface.Pass(), widget, requested_configuration),
503 fbo_(0),
504 current_surface_(0) {
505 for (auto& texture : textures_)
506 texture = 0;
507 }
508
509 unsigned int
510 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() {
511 return fbo_;
512 }
513
514 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext* context) {
515 if (!fbo_) {
516 glGenFramebuffersEXT(1, &fbo_);
517 if (!fbo_)
518 return false;
519 glGenTextures(arraysize(textures_), textures_);
520 if (!CreatePixmaps())
521 return false;
522 }
523 BindFramebuffer();
524 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
525 return SurfacelessEGL::OnMakeCurrent(context);
526 }
527
528 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size) {
529 if (size == GetSize())
530 return true;
531 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps();
532 }
533
534 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() {
535 return false;
536 }
537
538 gfx::SwapResult GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() {
539 if (!images_[current_surface_]->ScheduleOverlayPlane(
540 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
541 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
542 return gfx::SwapResult::SWAP_FAILED;
543 gfx::SwapResult result = GLSurfaceOzoneSurfaceless::SwapBuffers();
544 if (result != gfx::SwapResult::SWAP_ACK)
545 return result;
546 current_surface_ ^= 1;
547 BindFramebuffer();
548 return gfx::SwapResult::SWAP_ACK;
549 }
550
551 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync(
552 const SwapCompletionCallback& callback) {
553 if (!images_[current_surface_]->ScheduleOverlayPlane(
554 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
555 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
556 return false;
557 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback))
558 return false;
559 current_surface_ ^= 1;
560 BindFramebuffer();
561 return true;
562 }
563
564 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() {
565 GLContext* current_context = GLContext::GetCurrent();
566 DCHECK(current_context && current_context->IsCurrent(this));
567 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
568 if (fbo_) {
569 glDeleteTextures(arraysize(textures_), textures_);
570 for (auto& texture : textures_)
571 texture = 0;
572 glDeleteFramebuffersEXT(1, &fbo_);
573 fbo_ = 0;
574 }
575 for (auto image : images_) {
576 if (image)
577 image->Destroy(true);
578 }
579 }
580
581 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() {
582 DCHECK(!fbo_);
583 for (size_t i = 0; i < arraysize(textures_); i++)
584 DCHECK(!textures_[i]) << "texture " << i << " not released";
585 }
586
587 void GLSurfaceOzoneSurfacelessSurfaceImpl::BindFramebuffer() {
588 ScopedFrameBufferBinder fb(fbo_);
589 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
590 textures_[current_surface_], 0);
591 }
592
593 bool GLSurfaceOzoneSurfacelessSurfaceImpl::CreatePixmaps() {
594 if (!fbo_)
595 return true;
596 for (size_t i = 0; i < arraysize(textures_); i++) {
597 scoped_refptr<ui::NativePixmap> pixmap =
598 ui::OzonePlatform::GetInstance()
599 ->GetSurfaceFactoryOzone()
600 ->CreateNativePixmap(widget_, GetSize(),
601 ui::SurfaceFactoryOzone::BGRA_8888,
602 ui::SurfaceFactoryOzone::SCANOUT);
603 if (!pixmap)
604 return false;
605 scoped_refptr<SurfaceImage> image =
606 new SurfaceImage(GetSize(), GL_BGRA_EXT);
607 if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888))
608 return false;
609 images_[i] = image;
610 // Bind image to texture.
611 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]);
612 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
613 return false;
614 }
615 return true;
616 }
617
393 } // namespace 618 } // namespace
394 619
395 // static 620 // static
396 bool GLSurface::InitializeOneOffInternal() { 621 bool GLSurface::InitializeOneOffInternal() {
397 switch (GetGLImplementation()) { 622 switch (GetGLImplementation()) {
398 case kGLImplementationEGLGLES2: 623 case kGLImplementationEGLGLES2:
399 if (!GLSurfaceEGL::InitializeOneOff()) { 624 if (!GLSurfaceEGL::InitializeOneOff()) {
400 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; 625 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
401 return false; 626 return false;
402 } 627 }
403 628
404 return true; 629 return true;
405 case kGLImplementationOSMesaGL: 630 case kGLImplementationOSMesaGL:
406 case kGLImplementationMockGL: 631 case kGLImplementationMockGL:
407 return true; 632 return true;
408 default: 633 default:
409 return false; 634 return false;
410 } 635 }
411 } 636 }
412 637
413 // static 638 // static
414 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface( 639 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface(
415 gfx::AcceleratedWidget window) { 640 gfx::AcceleratedWidget window,
641 const gfx::SurfaceConfiguration& requested_configuration) {
416 if (GetGLImplementation() == kGLImplementationEGLGLES2 && 642 if (GetGLImplementation() == kGLImplementationEGLGLES2 &&
417 window != kNullAcceleratedWidget && 643 window != kNullAcceleratedWidget &&
418 GLSurfaceEGL::IsEGLSurfacelessContextSupported() && 644 GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
419 ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) { 645 ui::OzonePlatform::GetInstance()
646 ->GetSurfaceFactoryOzone()
647 ->CanShowPrimaryPlaneAsOverlay()) {
420 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 648 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
421 ui::SurfaceFactoryOzone::GetInstance() 649 ui::OzonePlatform::GetInstance()
650 ->GetSurfaceFactoryOzone()
422 ->CreateSurfacelessEGLSurfaceForWidget(window); 651 ->CreateSurfacelessEGLSurfaceForWidget(window);
423 if (!surface_ozone) 652 if (!surface_ozone)
424 return nullptr; 653 return nullptr;
425 scoped_refptr<GLSurface> surface; 654 scoped_refptr<GLSurface> surface;
426 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window); 655 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(),
656 window,
657 requested_configuration);
427 if (surface->Initialize()) 658 if (surface->Initialize())
428 return surface; 659 return surface;
429 } 660 }
430 661
431 return nullptr; 662 return nullptr;
432 } 663 }
433 664
434 // static 665 // static
435 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( 666 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
436 gfx::AcceleratedWidget window) { 667 gfx::AcceleratedWidget window,
668 const gfx::SurfaceConfiguration& requested_configuration) {
437 if (GetGLImplementation() == kGLImplementationOSMesaGL) { 669 if (GetGLImplementation() == kGLImplementationOSMesaGL) {
438 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless()); 670 scoped_refptr<GLSurface> surface(
671 new GLSurfaceOSMesaHeadless(requested_configuration));
439 if (!surface->Initialize()) 672 if (!surface->Initialize())
440 return NULL; 673 return NULL;
441 return surface; 674 return surface;
442 } 675 }
443 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); 676 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2);
444 if (window != kNullAcceleratedWidget) { 677 if (window != kNullAcceleratedWidget) {
445 scoped_refptr<GLSurface> surface; 678 scoped_refptr<GLSurface> surface;
446 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && 679 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
447 ui::SurfaceFactoryOzone::GetInstance() 680 ui::OzonePlatform::GetInstance()
681 ->GetSurfaceFactoryOzone()
448 ->CanShowPrimaryPlaneAsOverlay()) { 682 ->CanShowPrimaryPlaneAsOverlay()) {
449 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 683 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
450 ui::SurfaceFactoryOzone::GetInstance() 684 ui::OzonePlatform::GetInstance()
685 ->GetSurfaceFactoryOzone()
451 ->CreateSurfacelessEGLSurfaceForWidget(window); 686 ->CreateSurfacelessEGLSurfaceForWidget(window);
452 if (!surface_ozone) 687 if (!surface_ozone)
453 return NULL; 688 return NULL;
454 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(), 689 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(
455 window); 690 surface_ozone.Pass(), window, requested_configuration);
456 } else { 691 } else {
457 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 692 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
458 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget( 693 ui::OzonePlatform::GetInstance()
459 window); 694 ->GetSurfaceFactoryOzone()
695 ->CreateEGLSurfaceForWidget(window);
460 if (!surface_ozone) 696 if (!surface_ozone)
461 return NULL; 697 return NULL;
462 698
463 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window); 699 surface = new GLSurfaceOzoneEGL(
700 surface_ozone.Pass(), window, requested_configuration);
464 } 701 }
465 if (!surface->Initialize()) 702 if (!surface->Initialize())
466 return NULL; 703 return NULL;
467 return surface; 704 return surface;
468 } else { 705 } else {
469 scoped_refptr<GLSurface> surface = new GLSurfaceStub(); 706 scoped_refptr<GLSurface> surface = new GLSurfaceStub(
707 requested_configuration);
470 if (surface->Initialize()) 708 if (surface->Initialize())
471 return surface; 709 return surface;
472 } 710 }
473 return NULL; 711 return NULL;
474 } 712 }
475 713
476 // static 714 // static
477 scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface( 715 scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
478 const gfx::Size& size) { 716 const gfx::Size& size,
717 const gfx::SurfaceConfiguration& requested_configuration) {
479 switch (GetGLImplementation()) { 718 switch (GetGLImplementation()) {
480 case kGLImplementationOSMesaGL: { 719 case kGLImplementationOSMesaGL: {
481 scoped_refptr<GLSurface> surface( 720 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa(
482 new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, size)); 721 OSMesaSurfaceFormatBGRA, size, requested_configuration));
483 if (!surface->Initialize()) 722 if (!surface->Initialize())
484 return NULL; 723 return NULL;
485 724
486 return surface; 725 return surface;
487 } 726 }
488 case kGLImplementationEGLGLES2: { 727 case kGLImplementationEGLGLES2: {
489 scoped_refptr<GLSurface> surface; 728 scoped_refptr<GLSurface> surface;
490 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && 729 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
491 (size.width() == 0 && size.height() == 0)) { 730 (size.width() == 0 && size.height() == 0)) {
492 surface = new SurfacelessEGL(size); 731 surface = new SurfacelessEGL(size, requested_configuration);
493 } else 732 } else
494 surface = new PbufferGLSurfaceEGL(size); 733 surface = new PbufferGLSurfaceEGL(size, requested_configuration);
495 734
496 if (!surface->Initialize()) 735 if (!surface->Initialize())
497 return NULL; 736 return NULL;
498 return surface; 737 return surface;
499 } 738 }
739 case kGLImplementationMockGL:
740 return new GLSurfaceStub(requested_configuration);
500 default: 741 default:
501 NOTREACHED(); 742 NOTREACHED();
502 return NULL; 743 return NULL;
503 } 744 }
504 } 745 }
505 746
506 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { 747 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
507 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); 748 return ui::OzonePlatform::GetInstance()
749 ->GetSurfaceFactoryOzone()
750 ->GetNativeDisplay();
508 } 751 }
509 752
510 } // namespace gfx 753 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/gl_surface_osmesa.cc ('k') | ui/gl/gl_surface_stub.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698