Commit 7b49ae6d authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Make DirectCompositionSurfaceWin support PresentationCallback

Use GLSurfacePresentationHelper to support PresentationCallback in
DirectCompositionSurfaceWin.

Bug: 804970
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I50931d5b59dfea70d5e333abf0398144c8823bb3
Reviewed-on: https://chromium-review.googlesource.com/881710
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532938}
parent 88083f4e
......@@ -35,6 +35,7 @@
#include "ui/gl/gl_image_dxgi.h"
#include "ui/gl/gl_image_memory.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_surface_presentation_helper.h"
#include "ui/gl/scoped_make_current.h"
#ifndef EGL_ANGLE_flexible_surface_compatibility
......@@ -1205,10 +1206,16 @@ bool DirectCompositionSurfaceWin::Initialize(gl::GLSurfaceFormat format) {
return false;
}
return RecreateRootSurface();
if (!RecreateRootSurface())
return false;
presentation_helper_ =
std::make_unique<gl::GLSurfacePresentationHelper>(vsync_provider_.get());
return true;
}
void DirectCompositionSurfaceWin::Destroy() {
presentation_helper_ = nullptr;
if (default_surface_) {
if (!eglDestroySurface(GetDisplay(), default_surface_)) {
DLOG(ERROR) << "eglDestroySurface failed with error "
......@@ -1254,12 +1261,15 @@ bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size,
gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers(
const PresentationCallback& callback) {
gl::GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
presentation_helper_.get(), callback);
ui::ScopedReleaseCurrent release_current;
root_surface_->SwapBuffers(callback);
root_surface_->SwapBuffers(PresentationCallback());
layer_tree_->CommitAndClearPendingOverlays();
child_window_.ClearInvalidContents();
return release_current.Restore() ? gfx::SwapResult::SWAP_ACK
: gfx::SwapResult::SWAP_FAILED;
if (!release_current.Restore())
scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED);
return scoped_swap_buffers.result();
}
gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer(
......@@ -1298,6 +1308,8 @@ bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() {
}
bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) {
if (presentation_helper_)
presentation_helper_->OnMakeCurrent(context, this);
if (root_surface_)
return root_surface_->OnMakeCurrent(context);
return true;
......
......@@ -18,6 +18,10 @@
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_surface_egl.h"
namespace gl {
class GLSurfacePresentationHelper;
}
namespace gpu {
class DCLayerTree;
......@@ -107,6 +111,7 @@ class GPU_IPC_SERVICE_EXPORT DirectCompositionSurfaceWin
bool is_hdr_ = false;
bool has_alpha_ = true;
std::unique_ptr<gfx::VSyncProvider> vsync_provider_;
std::unique_ptr<gl::GLSurfacePresentationHelper> presentation_helper_;
scoped_refptr<DirectCompositionChildSurfaceWin> root_surface_;
std::unique_ptr<DCLayerTree> layer_tree_;
......
......@@ -673,10 +673,10 @@ gfx::SwapResult NativeViewGLSurfaceGLX::SwapBuffers(
const PresentationCallback& callback) {
TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", "width",
GetSize().width(), "height", GetSize().height());
presentation_helper_->PreSwapBuffers(callback);
GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
presentation_helper_.get(), callback);
glXSwapBuffers(g_display, GetDrawableHandle());
presentation_helper_->PostSwapBuffers();
return gfx::SwapResult::SWAP_ACK;
return scoped_swap_buffers.result();
}
gfx::Size NativeViewGLSurfaceGLX::GetSize() {
......@@ -716,10 +716,11 @@ gfx::SwapResult NativeViewGLSurfaceGLX::PostSubBuffer(
int height,
const PresentationCallback& callback) {
DCHECK(g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer);
presentation_helper_->PreSwapBuffers(callback);
GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
presentation_helper_.get(), callback);
glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height);
presentation_helper_->PostSwapBuffers();
return gfx::SwapResult::SWAP_ACK;
return scoped_swap_buffers.result();
}
bool NativeViewGLSurfaceGLX::OnMakeCurrent(GLContext* context) {
......
......@@ -11,6 +11,19 @@
namespace gl {
GLSurfacePresentationHelper::ScopedSwapBuffers::ScopedSwapBuffers(
GLSurfacePresentationHelper* helper,
const GLSurface::PresentationCallback& callback)
: helper_(helper) {
if (helper_)
helper_->PreSwapBuffers(callback);
}
GLSurfacePresentationHelper::ScopedSwapBuffers::~ScopedSwapBuffers() {
if (helper_)
helper_->PostSwapBuffers(result_);
}
GLSurfacePresentationHelper::Frame::Frame(Frame&& other) = default;
GLSurfacePresentationHelper::Frame::Frame(
......@@ -25,9 +38,7 @@ operator=(Frame&& other) = default;
GLSurfacePresentationHelper::GLSurfacePresentationHelper(
gfx::VSyncProvider* vsync_provider)
: vsync_provider_(vsync_provider), weak_ptr_factory_(this) {
DCHECK(vsync_provider_);
}
: vsync_provider_(vsync_provider), weak_ptr_factory_(this) {}
GLSurfacePresentationHelper::GLSurfacePresentationHelper(
base::TimeTicks timebase,
......@@ -84,9 +95,21 @@ void GLSurfacePresentationHelper::PreSwapBuffers(
pending_frames_.push_back(Frame(std::move(timer), callback));
}
void GLSurfacePresentationHelper::PostSwapBuffers() {
void GLSurfacePresentationHelper::PostSwapBuffers(gfx::SwapResult result) {
DCHECK(!pending_frames_.empty());
if (result == gfx::SwapResult::SWAP_ACK && gpu_timing_client_) {
if (!waiting_for_vsync_parameters_)
CheckPendingFrames();
return;
}
auto frame = std::move(pending_frames_.back());
pending_frames_.pop_back();
if (frame.timer) {
bool has_context = gl_context_ && gl_context_->IsCurrent(surface_);
frame.timer->Destroy(has_context);
}
frame.callback.Run(gfx::PresentationFeedback());
}
void GLSurfacePresentationHelper::CheckPendingFrames() {
......@@ -109,6 +132,7 @@ void GLSurfacePresentationHelper::CheckPendingFrames() {
if (gl_context_ && !gl_context_->IsCurrent(surface_)) {
gpu_timing_client_ = nullptr;
for (auto& frame : pending_frames_) {
if (frame.timer)
frame.timer->Destroy(false /* has_context */);
frame.callback.Run(gfx::PresentationFeedback());
}
......
......@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "ui/gfx/swap_result.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_surface.h"
......@@ -26,6 +27,22 @@ class GPUTimer;
// implementations.
class GL_EXPORT GLSurfacePresentationHelper {
public:
class GL_EXPORT ScopedSwapBuffers {
public:
ScopedSwapBuffers(GLSurfacePresentationHelper* helper,
const GLSurface::PresentationCallback& callback);
~ScopedSwapBuffers();
void set_result(gfx::SwapResult result) { result_ = result; }
gfx::SwapResult result() const { return result_; }
private:
GLSurfacePresentationHelper* const helper_;
gfx::SwapResult result_ = gfx::SwapResult::SWAP_ACK;
DISALLOW_COPY_AND_ASSIGN(ScopedSwapBuffers);
};
explicit GLSurfacePresentationHelper(gfx::VSyncProvider* vsync_provider);
// For using fixed VSync provider.
......@@ -35,7 +52,7 @@ class GL_EXPORT GLSurfacePresentationHelper {
void OnMakeCurrent(GLContext* context, GLSurface* surface);
void PreSwapBuffers(const GLSurface::PresentationCallback& callback);
void PostSwapBuffers();
void PostSwapBuffers(gfx::SwapResult result);
private:
struct Frame {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment