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

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

Issue 1054073002: Change ozone async swap to fix overlay scheduling (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 | « no previous file | 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 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"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { 116 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
116 public: 117 public:
117 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, 118 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
118 AcceleratedWidget widget) 119 AcceleratedWidget widget)
119 : SurfacelessEGL(gfx::Size()), 120 : SurfacelessEGL(gfx::Size()),
120 ozone_surface_(ozone_surface.Pass()), 121 ozone_surface_(ozone_surface.Pass()),
121 widget_(widget), 122 widget_(widget),
122 has_implicit_external_sync_( 123 has_implicit_external_sync_(
123 HasEGLExtension("EGL_ARM_implicit_external_sync")), 124 HasEGLExtension("EGL_ARM_implicit_external_sync")),
124 last_swap_buffers_result_(true), 125 last_swap_buffers_result_(true),
125 weak_factory_(this) {} 126 weak_factory_(this) {
127 unsubmitted_frames_.push_back(new PendingFrame());
128 }
126 129
127 bool Initialize() override { 130 bool Initialize() override {
128 if (!SurfacelessEGL::Initialize()) 131 if (!SurfacelessEGL::Initialize())
129 return false; 132 return false;
130 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); 133 vsync_provider_ = ozone_surface_->CreateVSyncProvider();
131 if (!vsync_provider_) 134 if (!vsync_provider_)
132 return false; 135 return false;
133 return true; 136 return true;
134 } 137 }
135 bool Resize(const gfx::Size& size) override { 138 bool Resize(const gfx::Size& size) override {
(...skipping 11 matching lines...) Expand all
147 if (!fence) 150 if (!fence)
148 return false; 151 return false;
149 152
150 EGLDisplay display = GetDisplay(); 153 EGLDisplay display = GetDisplay();
151 WaitForFence(display, fence); 154 WaitForFence(display, fence);
152 eglDestroySyncKHR(display, fence); 155 eglDestroySyncKHR(display, fence);
153 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { 156 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
154 glFinish(); 157 glFinish();
155 } 158 }
156 159
160 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_);
161 unsubmitted_frames_.back()->overlays.clear();
162
157 return ozone_surface_->OnSwapBuffers(); 163 return ozone_surface_->OnSwapBuffers();
158 } 164 }
159 bool ScheduleOverlayPlane(int z_order, 165 bool ScheduleOverlayPlane(int z_order,
160 OverlayTransform transform, 166 OverlayTransform transform,
161 GLImage* image, 167 GLImage* image,
162 const Rect& bounds_rect, 168 const Rect& bounds_rect,
163 const RectF& crop_rect) override { 169 const RectF& crop_rect) override {
164 return image->ScheduleOverlayPlane( 170 unsubmitted_frames_.back()->overlays.push_back(PendingFrame::Overlay(
165 widget_, z_order, transform, bounds_rect, crop_rect); 171 z_order, transform, image, bounds_rect, crop_rect));
172 return true;
166 } 173 }
167 bool IsOffscreen() override { return false; } 174 bool IsOffscreen() override { return false; }
168 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } 175 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); }
169 bool SupportsPostSubBuffer() override { return true; } 176 bool SupportsPostSubBuffer() override { return true; }
170 bool PostSubBuffer(int x, int y, int width, int height) override { 177 bool PostSubBuffer(int x, int y, int width, int height) override {
171 // The actual sub buffer handling is handled at higher layers. 178 // The actual sub buffer handling is handled at higher layers.
172 SwapBuffers(); 179 SwapBuffers();
173 return true; 180 return true;
174 } 181 }
175 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { 182 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override {
176 glFlush(); 183 glFlush();
177 // TODO: the following should be replaced by a per surface flush as it gets 184 // TODO: the following should be replaced by a per surface flush as it gets
178 // implemented in GL drivers. 185 // implemented in GL drivers.
179 if (has_implicit_external_sync_) { 186 if (has_implicit_external_sync_) {
180 // If last swap failed, don't try to schedule new ones. 187 // If last swap failed, don't try to schedule new ones.
181 if (!last_swap_buffers_result_) { 188 if (!last_swap_buffers_result_) {
182 last_swap_buffers_result_ = true; 189 last_swap_buffers_result_ = true;
183 return false; 190 return false;
184 } 191 }
185 192
186 EGLSyncKHR fence = InsertFence(); 193 EGLSyncKHR fence = InsertFence();
187 if (!fence) 194 if (!fence)
188 return false; 195 return false;
189 196
190 base::Closure fence_wait_task = 197 base::Closure fence_wait_task =
191 base::Bind(&WaitForFence, GetDisplay(), fence); 198 base::Bind(&WaitForFence, GetDisplay(), fence);
192 199
200 PendingFrame* frame = unsubmitted_frames_.back();
201 frame->callback = callback;
193 base::Closure fence_retired_callback = 202 base::Closure fence_retired_callback =
194 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, 203 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
195 weak_factory_.GetWeakPtr(), fence, callback); 204 weak_factory_.GetWeakPtr(), fence, frame);
196 205
197 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task, 206 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
198 fence_retired_callback, false); 207 fence_retired_callback, false);
208 unsubmitted_frames_.push_back(new PendingFrame());
199 return true; 209 return true;
200 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { 210 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
201 glFinish(); 211 glFinish();
202 } 212 }
alexst (slow to review) 2015/04/02 19:48:53 I think you are missing: unsubmitted_frames_.back
203 return ozone_surface_->OnSwapBuffersAsync(callback); 213 return ozone_surface_->OnSwapBuffersAsync(callback);
204 } 214 }
205 bool PostSubBufferAsync(int x, 215 bool PostSubBufferAsync(int x,
206 int y, 216 int y,
207 int width, 217 int width,
208 int height, 218 int height,
209 const SwapCompletionCallback& callback) override { 219 const SwapCompletionCallback& callback) override {
210 return SwapBuffersAsync(callback); 220 return SwapBuffersAsync(callback);
211 } 221 }
212 222
213 protected: 223 protected:
224 struct PendingFrame {
225 struct Overlay {
226 Overlay(int z_order,
227 OverlayTransform transform,
228 GLImage* image,
229 const Rect& bounds_rect,
230 const RectF& crop_rect)
231 : z_order(z_order),
232 transform(transform),
233 image(image),
234 bounds_rect(bounds_rect),
235 crop_rect(crop_rect) {}
236
237 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget) const {
238 return image->ScheduleOverlayPlane(widget, z_order, transform,
239 bounds_rect, crop_rect);
240 }
241
242 int z_order;
243 OverlayTransform transform;
244 scoped_refptr<GLImage> image;
245 const Rect& bounds_rect;
246 const RectF& crop_rect;
247 };
248
249 PendingFrame() : ready(false) {}
250
251 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget) {
252 for (const auto& overlay : overlays)
253 if (!overlay.ScheduleOverlayPlane(widget))
254 return false;
255 return true;
256 }
257 bool ready;
258 std::vector<Overlay> overlays;
259 SwapCompletionCallback callback;
260 };
261
214 ~GLSurfaceOzoneSurfaceless() override { 262 ~GLSurfaceOzoneSurfaceless() override {
215 Destroy(); // EGL surface must be destroyed before SurfaceOzone 263 Destroy(); // EGL surface must be destroyed before SurfaceOzone
216 } 264 }
217 265
266 void SubmitFrames() {
267 while (!unsubmitted_frames_.empty() && unsubmitted_frames_.front()->ready) {
268 PendingFrame* frame = unsubmitted_frames_.front();
269 last_swap_buffers_result_ =
270 last_swap_buffers_result_ && frame->ScheduleOverlayPlanes(widget_) &&
271 ozone_surface_->OnSwapBuffersAsync(frame->callback);
272 unsubmitted_frames_.erase(unsubmitted_frames_.begin());
273 }
274 }
275
218 EGLSyncKHR InsertFence() { 276 EGLSyncKHR InsertFence() {
219 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, 277 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR,
220 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, 278 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM,
221 EGL_NONE}; 279 EGL_NONE};
222 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); 280 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
223 } 281 }
224 282
225 void FenceRetired(EGLSyncKHR fence, const SwapCompletionCallback& callback) { 283 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) {
226 eglDestroySyncKHR(GetDisplay(), fence); 284 eglDestroySyncKHR(GetDisplay(), fence);
227 last_swap_buffers_result_ = ozone_surface_->OnSwapBuffersAsync(callback); 285 frame->ready = true;
286 SubmitFrames();
228 } 287 }
229 288
230 // The native surface. Deleting this is allowed to free the EGLNativeWindow. 289 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
231 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; 290 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
232 AcceleratedWidget widget_; 291 AcceleratedWidget widget_;
233 scoped_ptr<VSyncProvider> vsync_provider_; 292 scoped_ptr<VSyncProvider> vsync_provider_;
293 ScopedVector<PendingFrame> unsubmitted_frames_;
234 bool has_implicit_external_sync_; 294 bool has_implicit_external_sync_;
235 bool last_swap_buffers_result_; 295 bool last_swap_buffers_result_;
236 296
237 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; 297 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_;
238 298
239 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); 299 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
240 }; 300 };
241 301
242 // This provides surface-like semantics implemented through surfaceless. 302 // This provides surface-like semantics implemented through surfaceless.
243 // A framebuffer is bound automatically. 303 // A framebuffer is bound automatically.
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 NOTREACHED(); 561 NOTREACHED();
502 return NULL; 562 return NULL;
503 } 563 }
504 } 564 }
505 565
506 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { 566 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
507 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); 567 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();
508 } 568 }
509 569
510 } // namespace gfx 570 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698