Chromium Code Reviews| 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/ozone/platform/drm/gpu/gbm_surfaceless.h" | 5 #include "ui/ozone/platform/drm/gpu/gbm_surfaceless.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 | 30 |
| 31 GbmSurfaceless::GbmSurfaceless(GbmSurfaceFactory* surface_factory, | 31 GbmSurfaceless::GbmSurfaceless(GbmSurfaceFactory* surface_factory, |
| 32 std::unique_ptr<DrmWindowProxy> window, | 32 std::unique_ptr<DrmWindowProxy> window, |
| 33 gfx::AcceleratedWidget widget) | 33 gfx::AcceleratedWidget widget) |
| 34 : SurfacelessEGL(gfx::Size()), | 34 : SurfacelessEGL(gfx::Size()), |
| 35 surface_factory_(surface_factory), | 35 surface_factory_(surface_factory), |
| 36 window_(std::move(window)), | 36 window_(std::move(window)), |
| 37 widget_(widget), | 37 widget_(widget), |
| 38 has_implicit_external_sync_( | 38 has_implicit_external_sync_( |
| 39 HasEGLExtension("EGL_ARM_implicit_external_sync")), | 39 HasEGLExtension("EGL_ARM_implicit_external_sync")), |
| 40 has_image_flush_external_( | |
| 41 HasEGLExtension("EGL_EXT_image_flush_external")), | |
|
marcheu
2017/05/02 21:10:14
hmm, note that we need this to happen somehow... B
Daniele Castagna
2017/05/02 21:23:31
This happens per image. Look at GLImageNativePixma
| |
| 42 weak_factory_(this) { | 40 weak_factory_(this) { |
| 43 surface_factory_->RegisterSurface(window_->widget(), this); | 41 surface_factory_->RegisterSurface(window_->widget(), this); |
| 44 unsubmitted_frames_.push_back(base::MakeUnique<PendingFrame>()); | 42 unsubmitted_frames_.push_back(base::MakeUnique<PendingFrame>()); |
| 45 } | 43 } |
| 46 | 44 |
| 47 void GbmSurfaceless::QueueOverlayPlane(const OverlayPlane& plane) { | 45 void GbmSurfaceless::QueueOverlayPlane(const OverlayPlane& plane) { |
| 48 planes_.push_back(plane); | 46 planes_.push_back(plane); |
| 49 } | 47 } |
| 50 | 48 |
| 51 bool GbmSurfaceless::Initialize(gl::GLSurfaceFormat format) { | 49 bool GbmSurfaceless::Initialize(gl::GLSurfaceFormat format) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 } | 96 } |
| 99 | 97 |
| 100 void GbmSurfaceless::SwapBuffersAsync(const SwapCompletionCallback& callback) { | 98 void GbmSurfaceless::SwapBuffersAsync(const SwapCompletionCallback& callback) { |
| 101 TRACE_EVENT0("drm", "GbmSurfaceless::SwapBuffersAsync"); | 99 TRACE_EVENT0("drm", "GbmSurfaceless::SwapBuffersAsync"); |
| 102 // If last swap failed, don't try to schedule new ones. | 100 // If last swap failed, don't try to schedule new ones. |
| 103 if (!last_swap_buffers_result_) { | 101 if (!last_swap_buffers_result_) { |
| 104 callback.Run(gfx::SwapResult::SWAP_FAILED); | 102 callback.Run(gfx::SwapResult::SWAP_FAILED); |
| 105 return; | 103 return; |
| 106 } | 104 } |
| 107 | 105 |
| 108 glFlush(); | |
| 109 unsubmitted_frames_.back()->Flush(); | 106 unsubmitted_frames_.back()->Flush(); |
| 110 | 107 |
| 111 SwapCompletionCallback surface_swap_callback = base::Bind( | 108 SwapCompletionCallback surface_swap_callback = base::Bind( |
| 112 &GbmSurfaceless::SwapCompleted, weak_factory_.GetWeakPtr(), callback); | 109 &GbmSurfaceless::SwapCompleted, weak_factory_.GetWeakPtr(), callback); |
| 113 | 110 |
| 114 PendingFrame* frame = unsubmitted_frames_.back().get(); | 111 PendingFrame* frame = unsubmitted_frames_.back().get(); |
| 115 frame->callback = surface_swap_callback; | 112 frame->callback = surface_swap_callback; |
| 116 unsubmitted_frames_.push_back(base::MakeUnique<PendingFrame>()); | 113 unsubmitted_frames_.push_back(base::MakeUnique<PendingFrame>()); |
| 117 | 114 |
| 118 // TODO: the following should be replaced by a per surface flush as it gets | 115 // TODO: the following should be replaced by a per surface flush as it gets |
| 119 // implemented in GL drivers. | 116 // implemented in GL drivers. |
| 120 if (has_implicit_external_sync_ || has_image_flush_external_) { | 117 EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); |
| 121 EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); | 118 if (!fence) { |
| 122 if (!fence) { | 119 callback.Run(gfx::SwapResult::SWAP_FAILED); |
| 123 callback.Run(gfx::SwapResult::SWAP_FAILED); | 120 return; |
| 124 return; | |
| 125 } | |
| 126 | |
| 127 base::Closure fence_wait_task = | |
| 128 base::Bind(&WaitForFence, GetDisplay(), fence); | |
| 129 | |
| 130 base::Closure fence_retired_callback = | |
| 131 base::Bind(&GbmSurfaceless::FenceRetired, weak_factory_.GetWeakPtr(), | |
| 132 fence, frame); | |
| 133 | |
| 134 base::PostTaskWithTraitsAndReply( | |
| 135 FROM_HERE, base::TaskTraits() | |
| 136 .WithShutdownBehavior( | |
| 137 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) | |
| 138 .MayBlock(), | |
| 139 fence_wait_task, fence_retired_callback); | |
| 140 return; // Defer frame submission until fence signals. | |
| 141 } | 121 } |
| 142 | 122 |
| 143 frame->ready = true; | 123 base::Closure fence_wait_task = |
| 144 SubmitFrame(); | 124 base::Bind(&WaitForFence, GetDisplay(), fence); |
| 125 | |
| 126 base::Closure fence_retired_callback = base::Bind( | |
| 127 &GbmSurfaceless::FenceRetired, weak_factory_.GetWeakPtr(), fence, frame); | |
| 128 | |
| 129 base::PostTaskWithTraitsAndReply( | |
| 130 FROM_HERE, | |
| 131 base::TaskTraits() | |
| 132 .WithShutdownBehavior( | |
| 133 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) | |
| 134 .MayBlock(), | |
| 135 fence_wait_task, fence_retired_callback); | |
| 145 } | 136 } |
| 146 | 137 |
| 147 void GbmSurfaceless::PostSubBufferAsync( | 138 void GbmSurfaceless::PostSubBufferAsync( |
| 148 int x, | 139 int x, |
| 149 int y, | 140 int y, |
| 150 int width, | 141 int width, |
| 151 int height, | 142 int height, |
| 152 const SwapCompletionCallback& callback) { | 143 const SwapCompletionCallback& callback) { |
| 153 // The actual sub buffer handling is handled at higher layers. | 144 // The actual sub buffer handling is handled at higher layers. |
| 154 SwapBuffersAsync(callback); | 145 SwapBuffersAsync(callback); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 unsubmitted_frames_.erase(unsubmitted_frames_.begin()); | 197 unsubmitted_frames_.erase(unsubmitted_frames_.begin()); |
| 207 swap_buffers_pending_ = true; | 198 swap_buffers_pending_ = true; |
| 208 | 199 |
| 209 if (!frame->ScheduleOverlayPlanes(widget_)) { | 200 if (!frame->ScheduleOverlayPlanes(widget_)) { |
| 210 // |callback| is a wrapper for SwapCompleted(). Call it to properly | 201 // |callback| is a wrapper for SwapCompleted(). Call it to properly |
| 211 // propagate the failed state. | 202 // propagate the failed state. |
| 212 frame->callback.Run(gfx::SwapResult::SWAP_FAILED); | 203 frame->callback.Run(gfx::SwapResult::SWAP_FAILED); |
| 213 return; | 204 return; |
| 214 } | 205 } |
| 215 | 206 |
| 216 if (IsUniversalDisplayLinkDevice()) | |
| 217 glFinish(); | |
| 218 | |
| 219 window_->SchedulePageFlip(planes_, frame->callback); | 207 window_->SchedulePageFlip(planes_, frame->callback); |
| 220 planes_.clear(); | 208 planes_.clear(); |
| 221 } | 209 } |
| 222 } | 210 } |
| 223 | 211 |
| 224 EGLSyncKHR GbmSurfaceless::InsertFence(bool implicit) { | 212 EGLSyncKHR GbmSurfaceless::InsertFence(bool implicit) { |
| 225 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, | 213 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, |
| 226 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, | 214 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, |
| 227 EGL_NONE}; | 215 EGL_NONE}; |
| 228 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, | 216 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 240 callback.Run(result); | 228 callback.Run(result); |
| 241 swap_buffers_pending_ = false; | 229 swap_buffers_pending_ = false; |
| 242 if (result == gfx::SwapResult::SWAP_FAILED) { | 230 if (result == gfx::SwapResult::SWAP_FAILED) { |
| 243 last_swap_buffers_result_ = false; | 231 last_swap_buffers_result_ = false; |
| 244 return; | 232 return; |
| 245 } | 233 } |
| 246 | 234 |
| 247 SubmitFrame(); | 235 SubmitFrame(); |
| 248 } | 236 } |
| 249 | 237 |
| 250 bool GbmSurfaceless::IsUniversalDisplayLinkDevice() { | |
| 251 return planes_.empty() ? false : planes_[0].buffer->RequiresGlFinish(); | |
| 252 } | |
| 253 | |
| 254 } // namespace ui | 238 } // namespace ui |
| OLD | NEW |