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

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

Issue 1091253003: [ozone] Keep the queue of surfaceless buffers inside gl_surface_ozone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: unittests 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 | ui/ozone/platform/drm/BUILD.gn » ('j') | 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"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { 116 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
117 public: 117 public:
118 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, 118 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
119 AcceleratedWidget widget) 119 AcceleratedWidget widget)
120 : SurfacelessEGL(gfx::Size()), 120 : SurfacelessEGL(gfx::Size()),
121 ozone_surface_(ozone_surface.Pass()), 121 ozone_surface_(ozone_surface.Pass()),
122 widget_(widget), 122 widget_(widget),
123 has_implicit_external_sync_( 123 has_implicit_external_sync_(
124 HasEGLExtension("EGL_ARM_implicit_external_sync")), 124 HasEGLExtension("EGL_ARM_implicit_external_sync")),
125 last_swap_buffers_result_(true), 125 last_swap_buffers_result_(true),
126 swap_buffers_pending_(false),
126 weak_factory_(this) { 127 weak_factory_(this) {
127 unsubmitted_frames_.push_back(new PendingFrame()); 128 unsubmitted_frames_.push_back(new PendingFrame());
128 } 129 }
129 130
130 bool Initialize() override { 131 bool Initialize() override {
131 if (!SurfacelessEGL::Initialize()) 132 if (!SurfacelessEGL::Initialize())
132 return false; 133 return false;
133 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); 134 vsync_provider_ = ozone_surface_->CreateVSyncProvider();
134 if (!vsync_provider_) 135 if (!vsync_provider_)
135 return false; 136 return false;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 } 174 }
174 bool IsOffscreen() override { return false; } 175 bool IsOffscreen() override { return false; }
175 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } 176 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); }
176 bool SupportsPostSubBuffer() override { return true; } 177 bool SupportsPostSubBuffer() override { return true; }
177 bool PostSubBuffer(int x, int y, int width, int height) override { 178 bool PostSubBuffer(int x, int y, int width, int height) override {
178 // The actual sub buffer handling is handled at higher layers. 179 // The actual sub buffer handling is handled at higher layers.
179 SwapBuffers(); 180 SwapBuffers();
180 return true; 181 return true;
181 } 182 }
182 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { 183 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override {
184 // If last swap failed, don't try to schedule new ones.
185 if (!last_swap_buffers_result_)
186 return false;
187
183 glFlush(); 188 glFlush();
189
190 base::Closure surface_swap_callback =
191 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted,
192 weak_factory_.GetWeakPtr(), callback);
193
194 PendingFrame* frame = unsubmitted_frames_.back();
195 frame->callback = surface_swap_callback;
196 unsubmitted_frames_.push_back(new PendingFrame());
197
184 // TODO: the following should be replaced by a per surface flush as it gets 198 // TODO: the following should be replaced by a per surface flush as it gets
185 // implemented in GL drivers. 199 // implemented in GL drivers.
186 if (has_implicit_external_sync_) { 200 if (has_implicit_external_sync_) {
187 // If last swap failed, don't try to schedule new ones.
188 if (!last_swap_buffers_result_) {
189 last_swap_buffers_result_ = true;
190 return false;
191 }
192
193 EGLSyncKHR fence = InsertFence(); 201 EGLSyncKHR fence = InsertFence();
194 if (!fence) 202 if (!fence)
195 return false; 203 return false;
196 204
197 base::Closure fence_wait_task = 205 base::Closure fence_wait_task =
198 base::Bind(&WaitForFence, GetDisplay(), fence); 206 base::Bind(&WaitForFence, GetDisplay(), fence);
199 207
200 PendingFrame* frame = unsubmitted_frames_.back();
201 frame->callback = callback;
202 base::Closure fence_retired_callback = 208 base::Closure fence_retired_callback =
203 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, 209 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
204 weak_factory_.GetWeakPtr(), fence, frame); 210 weak_factory_.GetWeakPtr(), fence, frame);
205 211
206 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task, 212 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
207 fence_retired_callback, false); 213 fence_retired_callback, false);
208 unsubmitted_frames_.push_back(new PendingFrame());
209 return true; 214 return true;
210 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { 215 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
211 glFinish(); 216 glFinish();
212 } 217 }
213 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); 218
214 unsubmitted_frames_.back()->overlays.clear(); 219 frame->ready = true;
215 return ozone_surface_->OnSwapBuffersAsync(callback); 220 SubmitFrame();
221 return last_swap_buffers_result_;
216 } 222 }
217 bool PostSubBufferAsync(int x, 223 bool PostSubBufferAsync(int x,
218 int y, 224 int y,
219 int width, 225 int width,
220 int height, 226 int height,
221 const SwapCompletionCallback& callback) override { 227 const SwapCompletionCallback& callback) override {
222 return SwapBuffersAsync(callback); 228 return SwapBuffersAsync(callback);
223 } 229 }
224 230
225 protected: 231 protected:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 } 264 }
259 bool ready; 265 bool ready;
260 std::vector<Overlay> overlays; 266 std::vector<Overlay> overlays;
261 SwapCompletionCallback callback; 267 SwapCompletionCallback callback;
262 }; 268 };
263 269
264 ~GLSurfaceOzoneSurfaceless() override { 270 ~GLSurfaceOzoneSurfaceless() override {
265 Destroy(); // EGL surface must be destroyed before SurfaceOzone 271 Destroy(); // EGL surface must be destroyed before SurfaceOzone
266 } 272 }
267 273
268 void SubmitFrames() { 274 void SubmitFrame() {
269 while (!unsubmitted_frames_.empty() && unsubmitted_frames_.front()->ready) { 275 DCHECK(!unsubmitted_frames_.empty());
270 PendingFrame* frame = unsubmitted_frames_.front(); 276
277 if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) {
278 scoped_ptr<PendingFrame> frame(unsubmitted_frames_.front());
279 unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin());
280 swap_buffers_pending_ = true;
281
271 last_swap_buffers_result_ = 282 last_swap_buffers_result_ =
272 last_swap_buffers_result_ && frame->ScheduleOverlayPlanes(widget_) && 283 frame->ScheduleOverlayPlanes(widget_) &&
273 ozone_surface_->OnSwapBuffersAsync(frame->callback); 284 ozone_surface_->OnSwapBuffersAsync(frame->callback);
274 unsubmitted_frames_.erase(unsubmitted_frames_.begin());
275 } 285 }
276 } 286 }
277 287
278 EGLSyncKHR InsertFence() { 288 EGLSyncKHR InsertFence() {
279 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, 289 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR,
280 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, 290 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM,
281 EGL_NONE}; 291 EGL_NONE};
282 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); 292 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
283 } 293 }
284 294
285 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) { 295 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) {
286 eglDestroySyncKHR(GetDisplay(), fence); 296 eglDestroySyncKHR(GetDisplay(), fence);
287 frame->ready = true; 297 frame->ready = true;
288 SubmitFrames(); 298 SubmitFrame();
299 }
300
301 void SwapCompleted(const SwapCompletionCallback& callback) {
302 callback.Run();
303 swap_buffers_pending_ = false;
304
305 SubmitFrame();
289 } 306 }
290 307
291 // The native surface. Deleting this is allowed to free the EGLNativeWindow. 308 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
292 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; 309 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
293 AcceleratedWidget widget_; 310 AcceleratedWidget widget_;
294 scoped_ptr<VSyncProvider> vsync_provider_; 311 scoped_ptr<VSyncProvider> vsync_provider_;
295 ScopedVector<PendingFrame> unsubmitted_frames_; 312 ScopedVector<PendingFrame> unsubmitted_frames_;
296 bool has_implicit_external_sync_; 313 bool has_implicit_external_sync_;
297 bool last_swap_buffers_result_; 314 bool last_swap_buffers_result_;
315 bool swap_buffers_pending_;
298 316
299 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; 317 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_;
300 318
301 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); 319 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
302 }; 320 };
303 321
304 // This provides surface-like semantics implemented through surfaceless. 322 // This provides surface-like semantics implemented through surfaceless.
305 // A framebuffer is bound automatically. 323 // A framebuffer is bound automatically.
306 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl 324 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
307 : public GLSurfaceOzoneSurfaceless { 325 : public GLSurfaceOzoneSurfaceless {
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 NOTREACHED(); 581 NOTREACHED();
564 return NULL; 582 return NULL;
565 } 583 }
566 } 584 }
567 585
568 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { 586 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
569 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); 587 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();
570 } 588 }
571 589
572 } // namespace gfx 590 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | ui/ozone/platform/drm/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698