OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/init/gl_surface_ozone.h" | 5 #include "ui/gl/init/gl_surface_ozone.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 int width, | 209 int width, |
210 int height, | 210 int height, |
211 const SwapCompletionCallback& callback) override; | 211 const SwapCompletionCallback& callback) override; |
212 EGLConfig GetConfig() override; | 212 EGLConfig GetConfig() override; |
213 | 213 |
214 protected: | 214 protected: |
215 struct PendingFrame { | 215 struct PendingFrame { |
216 PendingFrame(); | 216 PendingFrame(); |
217 | 217 |
218 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget); | 218 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget); |
| 219 void Flush(); |
219 | 220 |
220 bool ready; | 221 bool ready; |
221 std::vector<GLSurfaceOverlay> overlays; | 222 std::vector<GLSurfaceOverlay> overlays; |
222 SwapCompletionCallback callback; | 223 SwapCompletionCallback callback; |
223 }; | 224 }; |
224 | 225 |
225 ~GLSurfaceOzoneSurfaceless() override; | 226 ~GLSurfaceOzoneSurfaceless() override; |
226 | 227 |
227 void SubmitFrame(); | 228 void SubmitFrame(); |
228 | 229 |
229 EGLSyncKHR InsertFence(); | 230 EGLSyncKHR InsertFence(bool implicit); |
230 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame); | 231 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame); |
231 | 232 |
232 void SwapCompleted(const SwapCompletionCallback& callback, | 233 void SwapCompleted(const SwapCompletionCallback& callback, |
233 gfx::SwapResult result); | 234 gfx::SwapResult result); |
234 | 235 |
235 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | 236 // The native surface. Deleting this is allowed to free the EGLNativeWindow. |
236 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | 237 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
237 gfx::AcceleratedWidget widget_; | 238 gfx::AcceleratedWidget widget_; |
238 std::unique_ptr<gfx::VSyncProvider> vsync_provider_; | 239 std::unique_ptr<gfx::VSyncProvider> vsync_provider_; |
239 ScopedVector<PendingFrame> unsubmitted_frames_; | 240 ScopedVector<PendingFrame> unsubmitted_frames_; |
240 bool has_implicit_external_sync_; | 241 bool has_implicit_external_sync_; |
| 242 bool has_image_flush_external_; |
241 bool last_swap_buffers_result_; | 243 bool last_swap_buffers_result_; |
242 bool swap_buffers_pending_; | 244 bool swap_buffers_pending_; |
243 | 245 |
244 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; | 246 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; |
245 | 247 |
246 private: | 248 private: |
247 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); | 249 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); |
248 }; | 250 }; |
249 | 251 |
250 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {} | 252 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {} |
251 | 253 |
252 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes( | 254 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes( |
253 gfx::AcceleratedWidget widget) { | 255 gfx::AcceleratedWidget widget) { |
254 for (const auto& overlay : overlays) | 256 for (const auto& overlay : overlays) |
255 if (!overlay.ScheduleOverlayPlane(widget)) | 257 if (!overlay.ScheduleOverlayPlane(widget)) |
256 return false; | 258 return false; |
257 return true; | 259 return true; |
258 } | 260 } |
259 | 261 |
| 262 void GLSurfaceOzoneSurfaceless::PendingFrame::Flush() { |
| 263 for (const auto& overlay : overlays) |
| 264 overlay.Flush(); |
| 265 } |
| 266 |
260 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless( | 267 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless( |
261 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 268 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
262 gfx::AcceleratedWidget widget) | 269 gfx::AcceleratedWidget widget) |
263 : SurfacelessEGL(gfx::Size()), | 270 : SurfacelessEGL(gfx::Size()), |
264 ozone_surface_(std::move(ozone_surface)), | 271 ozone_surface_(std::move(ozone_surface)), |
265 widget_(widget), | 272 widget_(widget), |
266 has_implicit_external_sync_( | 273 has_implicit_external_sync_( |
267 HasEGLExtension("EGL_ARM_implicit_external_sync")), | 274 HasEGLExtension("EGL_ARM_implicit_external_sync")), |
| 275 has_image_flush_external_( |
| 276 HasEGLExtension("EGL_EXT_image_flush_external")), |
268 last_swap_buffers_result_(true), | 277 last_swap_buffers_result_(true), |
269 swap_buffers_pending_(false), | 278 swap_buffers_pending_(false), |
270 weak_factory_(this) { | 279 weak_factory_(this) { |
271 unsubmitted_frames_.push_back(new PendingFrame()); | 280 unsubmitted_frames_.push_back(new PendingFrame()); |
272 } | 281 } |
273 | 282 |
274 bool GLSurfaceOzoneSurfaceless::Initialize(GLSurface::Format format) { | 283 bool GLSurfaceOzoneSurfaceless::Initialize(GLSurface::Format format) { |
275 if (!SurfacelessEGL::Initialize(format)) | 284 if (!SurfacelessEGL::Initialize(format)) |
276 return false; | 285 return false; |
277 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); | 286 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); |
278 if (!vsync_provider_) | 287 if (!vsync_provider_) |
279 return false; | 288 return false; |
280 return true; | 289 return true; |
281 } | 290 } |
282 | 291 |
283 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size, | 292 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size, |
284 float scale_factor, | 293 float scale_factor, |
285 bool has_alpha) { | 294 bool has_alpha) { |
286 if (!ozone_surface_->ResizeNativeWindow(size)) | 295 if (!ozone_surface_->ResizeNativeWindow(size)) |
287 return false; | 296 return false; |
288 | 297 |
289 return SurfacelessEGL::Resize(size, scale_factor, has_alpha); | 298 return SurfacelessEGL::Resize(size, scale_factor, has_alpha); |
290 } | 299 } |
291 | 300 |
292 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() { | 301 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() { |
293 glFlush(); | 302 glFlush(); |
| 303 |
| 304 unsubmitted_frames_.back()->Flush(); |
| 305 |
294 // TODO: the following should be replaced by a per surface flush as it gets | 306 // TODO: the following should be replaced by a per surface flush as it gets |
295 // implemented in GL drivers. | 307 // implemented in GL drivers. |
296 if (has_implicit_external_sync_) { | 308 if (has_implicit_external_sync_ || has_image_flush_external_) { |
297 EGLSyncKHR fence = InsertFence(); | 309 EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); |
298 if (!fence) | 310 if (!fence) |
299 return gfx::SwapResult::SWAP_FAILED; | 311 return gfx::SwapResult::SWAP_FAILED; |
300 | 312 |
301 EGLDisplay display = GetDisplay(); | 313 EGLDisplay display = GetDisplay(); |
302 WaitForFence(display, fence); | 314 WaitForFence(display, fence); |
303 eglDestroySyncKHR(display, fence); | 315 eglDestroySyncKHR(display, fence); |
304 } | 316 } |
305 | 317 |
306 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); | 318 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); |
307 unsubmitted_frames_.back()->overlays.clear(); | 319 unsubmitted_frames_.back()->overlays.clear(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 363 |
352 void GLSurfaceOzoneSurfaceless::SwapBuffersAsync( | 364 void GLSurfaceOzoneSurfaceless::SwapBuffersAsync( |
353 const SwapCompletionCallback& callback) { | 365 const SwapCompletionCallback& callback) { |
354 // If last swap failed, don't try to schedule new ones. | 366 // If last swap failed, don't try to schedule new ones. |
355 if (!last_swap_buffers_result_) { | 367 if (!last_swap_buffers_result_) { |
356 callback.Run(gfx::SwapResult::SWAP_FAILED); | 368 callback.Run(gfx::SwapResult::SWAP_FAILED); |
357 return; | 369 return; |
358 } | 370 } |
359 | 371 |
360 glFlush(); | 372 glFlush(); |
| 373 unsubmitted_frames_.back()->Flush(); |
361 | 374 |
362 SwapCompletionCallback surface_swap_callback = | 375 SwapCompletionCallback surface_swap_callback = |
363 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, | 376 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, |
364 weak_factory_.GetWeakPtr(), callback); | 377 weak_factory_.GetWeakPtr(), callback); |
365 | 378 |
366 PendingFrame* frame = unsubmitted_frames_.back(); | 379 PendingFrame* frame = unsubmitted_frames_.back(); |
367 frame->callback = surface_swap_callback; | 380 frame->callback = surface_swap_callback; |
368 unsubmitted_frames_.push_back(new PendingFrame()); | 381 unsubmitted_frames_.push_back(new PendingFrame()); |
369 | 382 |
370 // TODO: the following should be replaced by a per surface flush as it gets | 383 // TODO: the following should be replaced by a per surface flush as it gets |
371 // implemented in GL drivers. | 384 // implemented in GL drivers. |
372 if (has_implicit_external_sync_) { | 385 if (has_implicit_external_sync_ || has_image_flush_external_) { |
373 EGLSyncKHR fence = InsertFence(); | 386 EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); |
374 if (!fence) { | 387 if (!fence) { |
375 callback.Run(gfx::SwapResult::SWAP_FAILED); | 388 callback.Run(gfx::SwapResult::SWAP_FAILED); |
376 return; | 389 return; |
377 } | 390 } |
378 | 391 |
379 base::Closure fence_wait_task = | 392 base::Closure fence_wait_task = |
380 base::Bind(&WaitForFence, GetDisplay(), fence); | 393 base::Bind(&WaitForFence, GetDisplay(), fence); |
381 | 394 |
382 base::Closure fence_retired_callback = | 395 base::Closure fence_retired_callback = |
383 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, | 396 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 return; | 444 return; |
432 } | 445 } |
433 | 446 |
434 if (ozone_surface_->IsUniversalDisplayLinkDevice()) | 447 if (ozone_surface_->IsUniversalDisplayLinkDevice()) |
435 glFinish(); | 448 glFinish(); |
436 | 449 |
437 ozone_surface_->OnSwapBuffersAsync(frame->callback); | 450 ozone_surface_->OnSwapBuffersAsync(frame->callback); |
438 } | 451 } |
439 } | 452 } |
440 | 453 |
441 EGLSyncKHR GLSurfaceOzoneSurfaceless::InsertFence() { | 454 EGLSyncKHR GLSurfaceOzoneSurfaceless::InsertFence(bool implicit) { |
442 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, | 455 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, |
443 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, | 456 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, |
444 EGL_NONE}; | 457 EGL_NONE}; |
445 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); | 458 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, |
| 459 implicit ? attrib_list : NULL); |
446 } | 460 } |
447 | 461 |
448 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence, | 462 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence, |
449 PendingFrame* frame) { | 463 PendingFrame* frame) { |
450 eglDestroySyncKHR(GetDisplay(), fence); | 464 eglDestroySyncKHR(GetDisplay(), fence); |
451 frame->ready = true; | 465 frame->ready = true; |
452 SubmitFrame(); | 466 SubmitFrame(); |
453 } | 467 } |
454 | 468 |
455 void GLSurfaceOzoneSurfaceless::SwapCompleted( | 469 void GLSurfaceOzoneSurfaceless::SwapCompleted( |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 ui::OzonePlatform::GetInstance() | 698 ui::OzonePlatform::GetInstance() |
685 ->GetSurfaceFactoryOzone() | 699 ->GetSurfaceFactoryOzone() |
686 ->CreateSurfacelessEGLSurfaceForWidget(window); | 700 ->CreateSurfacelessEGLSurfaceForWidget(window); |
687 if (!surface_ozone) | 701 if (!surface_ozone) |
688 return nullptr; | 702 return nullptr; |
689 return InitializeGLSurface(new GLSurfaceOzoneSurfacelessSurfaceImpl( | 703 return InitializeGLSurface(new GLSurfaceOzoneSurfacelessSurfaceImpl( |
690 std::move(surface_ozone), window)); | 704 std::move(surface_ozone), window)); |
691 } | 705 } |
692 | 706 |
693 } // namespace gl | 707 } // namespace gl |
OLD | NEW |