OLD | NEW |
---|---|
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 Loading... | |
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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 { |
183 glFlush(); | 184 glFlush(); |
185 | |
186 base::Closure surface_swap_callback = | |
187 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, | |
188 weak_factory_.GetWeakPtr(), callback); | |
189 | |
190 PendingFrame* frame = unsubmitted_frames_.back(); | |
191 frame->callback = surface_swap_callback; | |
192 unsubmitted_frames_.push_back(new PendingFrame()); | |
193 | |
184 // TODO: the following should be replaced by a per surface flush as it gets | 194 // TODO: the following should be replaced by a per surface flush as it gets |
185 // implemented in GL drivers. | 195 // implemented in GL drivers. |
186 if (has_implicit_external_sync_) { | 196 if (has_implicit_external_sync_) { |
187 // If last swap failed, don't try to schedule new ones. | 197 // If last swap failed, don't try to schedule new ones. |
188 if (!last_swap_buffers_result_) { | 198 if (!last_swap_buffers_result_) { |
189 last_swap_buffers_result_ = true; | 199 last_swap_buffers_result_ = true; |
190 return false; | 200 return false; |
191 } | 201 } |
192 | 202 |
193 EGLSyncKHR fence = InsertFence(); | 203 EGLSyncKHR fence = InsertFence(); |
194 if (!fence) | 204 if (!fence) |
195 return false; | 205 return false; |
196 | 206 |
197 base::Closure fence_wait_task = | 207 base::Closure fence_wait_task = |
198 base::Bind(&WaitForFence, GetDisplay(), fence); | 208 base::Bind(&WaitForFence, GetDisplay(), fence); |
199 | 209 |
200 PendingFrame* frame = unsubmitted_frames_.back(); | |
201 frame->callback = callback; | |
202 base::Closure fence_retired_callback = | 210 base::Closure fence_retired_callback = |
203 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, | 211 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, |
204 weak_factory_.GetWeakPtr(), fence, frame); | 212 weak_factory_.GetWeakPtr(), fence, frame); |
205 | 213 |
206 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task, | 214 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task, |
207 fence_retired_callback, false); | 215 fence_retired_callback, false); |
208 unsubmitted_frames_.push_back(new PendingFrame()); | |
209 return true; | 216 return true; |
210 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { | 217 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { |
spang
2015/04/21 19:39:36
Can you fix the style guide violation here?
No el
| |
211 glFinish(); | 218 glFinish(); |
212 } | 219 } |
213 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); | 220 |
214 unsubmitted_frames_.back()->overlays.clear(); | 221 frame->ready = true; |
215 return ozone_surface_->OnSwapBuffersAsync(callback); | 222 SubmitFrame(); |
223 return last_swap_buffers_result_; | |
216 } | 224 } |
217 bool PostSubBufferAsync(int x, | 225 bool PostSubBufferAsync(int x, |
218 int y, | 226 int y, |
219 int width, | 227 int width, |
220 int height, | 228 int height, |
221 const SwapCompletionCallback& callback) override { | 229 const SwapCompletionCallback& callback) override { |
222 return SwapBuffersAsync(callback); | 230 return SwapBuffersAsync(callback); |
223 } | 231 } |
224 | 232 |
225 protected: | 233 protected: |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
258 } | 266 } |
259 bool ready; | 267 bool ready; |
260 std::vector<Overlay> overlays; | 268 std::vector<Overlay> overlays; |
261 SwapCompletionCallback callback; | 269 SwapCompletionCallback callback; |
262 }; | 270 }; |
263 | 271 |
264 ~GLSurfaceOzoneSurfaceless() override { | 272 ~GLSurfaceOzoneSurfaceless() override { |
265 Destroy(); // EGL surface must be destroyed before SurfaceOzone | 273 Destroy(); // EGL surface must be destroyed before SurfaceOzone |
266 } | 274 } |
267 | 275 |
268 void SubmitFrames() { | 276 void SubmitFrame() { |
269 while (!unsubmitted_frames_.empty() && unsubmitted_frames_.front()->ready) { | 277 DCHECK(!unsubmitted_frames_.empty()); |
270 PendingFrame* frame = unsubmitted_frames_.front(); | 278 |
279 if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) { | |
280 scoped_ptr<PendingFrame> frame(unsubmitted_frames_.front()); | |
281 unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin()); | |
282 swap_buffers_pending_ = true; | |
283 | |
271 last_swap_buffers_result_ = | 284 last_swap_buffers_result_ = |
272 last_swap_buffers_result_ && frame->ScheduleOverlayPlanes(widget_) && | 285 frame->ScheduleOverlayPlanes(widget_) && |
273 ozone_surface_->OnSwapBuffersAsync(frame->callback); | 286 ozone_surface_->OnSwapBuffersAsync(frame->callback); |
274 unsubmitted_frames_.erase(unsubmitted_frames_.begin()); | |
275 } | 287 } |
276 } | 288 } |
277 | 289 |
278 EGLSyncKHR InsertFence() { | 290 EGLSyncKHR InsertFence() { |
279 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, | 291 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, |
280 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, | 292 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, |
281 EGL_NONE}; | 293 EGL_NONE}; |
282 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); | 294 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); |
283 } | 295 } |
284 | 296 |
285 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) { | 297 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) { |
286 eglDestroySyncKHR(GetDisplay(), fence); | 298 eglDestroySyncKHR(GetDisplay(), fence); |
287 frame->ready = true; | 299 frame->ready = true; |
288 SubmitFrames(); | 300 SubmitFrame(); |
301 } | |
302 | |
303 void SwapCompleted(const SwapCompletionCallback& callback) { | |
304 callback.Run(); | |
305 swap_buffers_pending_ = false; | |
306 | |
307 SubmitFrame(); | |
289 } | 308 } |
290 | 309 |
291 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | 310 // The native surface. Deleting this is allowed to free the EGLNativeWindow. |
292 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | 311 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
293 AcceleratedWidget widget_; | 312 AcceleratedWidget widget_; |
294 scoped_ptr<VSyncProvider> vsync_provider_; | 313 scoped_ptr<VSyncProvider> vsync_provider_; |
295 ScopedVector<PendingFrame> unsubmitted_frames_; | 314 ScopedVector<PendingFrame> unsubmitted_frames_; |
296 bool has_implicit_external_sync_; | 315 bool has_implicit_external_sync_; |
297 bool last_swap_buffers_result_; | 316 bool last_swap_buffers_result_; |
spang
2015/04/21 19:39:36
Can someone explain what last_swap_buffers_result_
| |
317 bool swap_buffers_pending_; | |
298 | 318 |
299 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; | 319 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; |
300 | 320 |
301 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); | 321 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); |
302 }; | 322 }; |
303 | 323 |
304 // This provides surface-like semantics implemented through surfaceless. | 324 // This provides surface-like semantics implemented through surfaceless. |
305 // A framebuffer is bound automatically. | 325 // A framebuffer is bound automatically. |
306 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl | 326 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl |
307 : public GLSurfaceOzoneSurfaceless { | 327 : public GLSurfaceOzoneSurfaceless { |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 NOTREACHED(); | 583 NOTREACHED(); |
564 return NULL; | 584 return NULL; |
565 } | 585 } |
566 } | 586 } |
567 | 587 |
568 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { | 588 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { |
569 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); | 589 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); |
570 } | 590 } |
571 | 591 |
572 } // namespace gfx | 592 } // namespace gfx |
OLD | NEW |