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

Side by Side Diff: ui/ozone/platform/drm/gpu/gbm_surfaceless.cc

Issue 2858693002: ozone: Wait on EGLFence before committing buffers. Avoid using GL. (Closed)
Patch Set: Rebase on master. Created 3 years, 7 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/ozone/platform/drm/gpu/gbm_surfaceless.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/ozone/platform/drm/gpu/gbm_surfaceless.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698