| 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 |