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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gl/gl_surface_ozone.cc
diff --git a/ui/gl/gl_surface_ozone.cc b/ui/gl/gl_surface_ozone.cc
index 800be1759fe96331573944463123e00ce19968f2..ba7b02b036814056100705915fcd4bd4033603a5 100644
--- a/ui/gl/gl_surface_ozone.cc
+++ b/ui/gl/gl_surface_ozone.cc
@@ -9,6 +9,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/worker_pool.h"
#include "ui/gfx/native_widget_types.h"
@@ -122,7 +123,9 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
has_implicit_external_sync_(
HasEGLExtension("EGL_ARM_implicit_external_sync")),
last_swap_buffers_result_(true),
- weak_factory_(this) {}
+ weak_factory_(this) {
+ unsubmitted_frames_.push_back(new PendingFrame());
+ }
bool Initialize() override {
if (!SurfacelessEGL::Initialize())
@@ -154,6 +157,9 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
glFinish();
}
+ unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_);
+ unsubmitted_frames_.back()->overlays.clear();
+
return ozone_surface_->OnSwapBuffers();
}
bool ScheduleOverlayPlane(int z_order,
@@ -161,8 +167,9 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
GLImage* image,
const Rect& bounds_rect,
const RectF& crop_rect) override {
- return image->ScheduleOverlayPlane(
- widget_, z_order, transform, bounds_rect, crop_rect);
+ unsubmitted_frames_.back()->overlays.push_back(PendingFrame::Overlay(
+ z_order, transform, image, bounds_rect, crop_rect));
+ return true;
}
bool IsOffscreen() override { return false; }
VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); }
@@ -190,16 +197,21 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
base::Closure fence_wait_task =
base::Bind(&WaitForFence, GetDisplay(), fence);
+ PendingFrame* frame = unsubmitted_frames_.back();
+ frame->callback = callback;
base::Closure fence_retired_callback =
base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
- weak_factory_.GetWeakPtr(), fence, callback);
+ weak_factory_.GetWeakPtr(), fence, frame);
base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
fence_retired_callback, false);
+ unsubmitted_frames_.push_back(new PendingFrame());
return true;
} else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
glFinish();
}
+ unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_);
+ unsubmitted_frames_.back()->overlays.clear();
return ozone_surface_->OnSwapBuffersAsync(callback);
}
bool PostSubBufferAsync(int x,
@@ -211,10 +223,58 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
}
protected:
+ struct PendingFrame {
+ struct Overlay {
+ Overlay(int z_order,
+ OverlayTransform transform,
+ GLImage* image,
+ const Rect& bounds_rect,
+ const RectF& crop_rect)
+ : z_order(z_order),
+ transform(transform),
+ image(image),
+ bounds_rect(bounds_rect),
+ crop_rect(crop_rect) {}
+
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget) const {
+ return image->ScheduleOverlayPlane(widget, z_order, transform,
+ bounds_rect, crop_rect);
+ }
+
+ int z_order;
+ OverlayTransform transform;
+ scoped_refptr<GLImage> image;
+ Rect bounds_rect;
+ RectF crop_rect;
+ };
+
+ PendingFrame() : ready(false) {}
+
+ bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget) {
+ for (const auto& overlay : overlays)
+ if (!overlay.ScheduleOverlayPlane(widget))
+ return false;
+ return true;
+ }
+ bool ready;
+ std::vector<Overlay> overlays;
+ SwapCompletionCallback callback;
+ };
+
~GLSurfaceOzoneSurfaceless() override {
Destroy(); // EGL surface must be destroyed before SurfaceOzone
}
+ void SubmitFrames() {
+ while (!unsubmitted_frames_.empty() && unsubmitted_frames_.front()->ready) {
+ PendingFrame* frame = unsubmitted_frames_.front();
+ last_swap_buffers_result_ =
+ last_swap_buffers_result_ && frame->ScheduleOverlayPlanes(widget_) &&
+ ozone_surface_->OnSwapBuffersAsync(frame->callback);
+ unsubmitted_frames_.erase(unsubmitted_frames_.begin());
+ }
+ }
+
EGLSyncKHR InsertFence() {
const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR,
EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM,
@@ -222,15 +282,17 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
}
- void FenceRetired(EGLSyncKHR fence, const SwapCompletionCallback& callback) {
+ void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) {
eglDestroySyncKHR(GetDisplay(), fence);
- last_swap_buffers_result_ = ozone_surface_->OnSwapBuffersAsync(callback);
+ frame->ready = true;
+ SubmitFrames();
}
// The native surface. Deleting this is allowed to free the EGLNativeWindow.
scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
AcceleratedWidget widget_;
scoped_ptr<VSyncProvider> vsync_provider_;
+ ScopedVector<PendingFrame> unsubmitted_frames_;
bool has_implicit_external_sync_;
bool last_swap_buffers_result_;
« 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