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

Unified Diff: gpu/ipc/service/direct_composition_surface_win.cc

Issue 2743663006: Allow switching DirectCompositionSurfaceWin between drawing modes. (Closed)
Patch Set: rebase Created 3 years, 9 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
Index: gpu/ipc/service/direct_composition_surface_win.cc
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc
index 48a8cd93114461a054e5c09a3bfb5fb5d600cc95..7f65213481bc0c2f4b7a61aa60731668c3259097 100644
--- a/gpu/ipc/service/direct_composition_surface_win.cc
+++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -5,6 +5,7 @@
#include "gpu/ipc/service/direct_composition_surface_win.h"
#include "base/optional.h"
+#include "base/synchronization/waitable_event.h"
#include "gpu/ipc/service/gpu_channel_manager.h"
#include "gpu/ipc/service/gpu_channel_manager_delegate.h"
#include "gpu/ipc/service/switches.h"
@@ -154,32 +155,83 @@ bool DirectCompositionSurfaceWin::Initialize(gl::GLSurfaceFormat format) {
eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]);
CHECK(!!default_surface_);
- InitializeSurface();
-
return true;
}
-void DirectCompositionSurfaceWin::InitializeSurface() {
- ScopedReleaseCurrent release_current(this);
- ReleaseDrawTexture();
+void DirectCompositionSurfaceWin::ReleaseCurrentSurface() {
+ ReleaseDrawTexture(true);
dcomp_surface_.Release();
- HRESULT hr = dcomp_device_->CreateSurface(
- size_.width(), size_.height(), DXGI_FORMAT_B8G8R8A8_UNORM,
- DXGI_ALPHA_MODE_PREMULTIPLIED, dcomp_surface_.Receive());
- has_been_rendered_to_ = false;
+ swap_chain_.Release();
+}
- CHECK(SUCCEEDED(hr));
+void DirectCompositionSurfaceWin::InitializeSurface() {
+ DCHECK(!dcomp_surface_);
+ DCHECK(!swap_chain_);
+ if (enable_dc_layers_) {
+ HRESULT hr = dcomp_device_->CreateSurface(
+ size_.width(), size_.height(), DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_ALPHA_MODE_PREMULTIPLIED, dcomp_surface_.Receive());
+ has_been_rendered_to_ = false;
+ CHECK(SUCCEEDED(hr));
+ } else {
+ base::win::ScopedComPtr<IDXGIDevice> dxgi_device;
+ d3d11_device_.QueryInterface(dxgi_device.Receive());
+ base::win::ScopedComPtr<IDXGIAdapter> dxgi_adapter;
+ dxgi_device->GetAdapter(dxgi_adapter.Receive());
+ base::win::ScopedComPtr<IDXGIFactory2> dxgi_factory;
+ dxgi_adapter->GetParent(IID_PPV_ARGS(dxgi_factory.Receive()));
+
+ DXGI_SWAP_CHAIN_DESC1 desc = {};
+ desc.Width = size_.width();
+ desc.Height = size_.height();
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.Stereo = FALSE;
+ desc.SampleDesc.Count = 1;
+ desc.BufferCount = 2;
+ desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ desc.Scaling = DXGI_SCALING_STRETCH;
+ desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
+ desc.Flags = 0;
+ HRESULT hr = dxgi_factory->CreateSwapChainForComposition(
+ d3d11_device_.get(), &desc, nullptr, swap_chain_.Receive());
+ has_been_rendered_to_ = false;
+ first_swap_ = true;
+ CHECK(SUCCEEDED(hr));
+ }
}
-void DirectCompositionSurfaceWin::ReleaseDrawTexture() {
+void DirectCompositionSurfaceWin::ReleaseDrawTexture(bool will_discard) {
if (real_surface_) {
eglDestroySurface(GetDisplay(), real_surface_);
real_surface_ = nullptr;
}
if (draw_texture_) {
draw_texture_.Release();
- HRESULT hr = dcomp_surface_->EndDraw();
- CHECK(SUCCEEDED(hr));
+ if (dcomp_surface_) {
+ HRESULT hr = dcomp_surface_->EndDraw();
+ CHECK(SUCCEEDED(hr));
+ } else if (!will_discard) {
+ DXGI_PRESENT_PARAMETERS params = {};
+ RECT dirty_rect = swap_rect_.ToRECT();
+ params.DirtyRectsCount = 1;
+ params.pDirtyRects = &dirty_rect;
+ swap_chain_->Present1(first_swap_ ? 0 : 1, 0, &params);
+ if (first_swap_) {
+ // Wait for the GPU to finish executing its commands before
+ // committing the DirectComposition tree, or else the swapchain
+ // may flicker black when it's first presented.
+ base::win::ScopedComPtr<IDXGIDevice2> dxgi_device2;
+ HRESULT hr = d3d11_device_.QueryInterface(dxgi_device2.Receive());
+ DCHECK(SUCCEEDED(hr));
+ base::WaitableEvent event(
+ base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ dxgi_device2->EnqueueSetEvent(event.handle());
+ event.Wait();
+ first_swap_ = false;
+ }
+ }
}
if (dcomp_surface_ == g_current_surface)
g_current_surface = nullptr;
@@ -200,8 +252,11 @@ void DirectCompositionSurfaceWin::Destroy() {
}
real_surface_ = nullptr;
}
- if (dcomp_surface_ == g_current_surface)
+ if (dcomp_surface_ && (dcomp_surface_ == g_current_surface)) {
+ HRESULT hr = dcomp_surface_->EndDraw();
+ CHECK(SUCCEEDED(hr));
g_current_surface = nullptr;
+ }
draw_texture_.Release();
dcomp_surface_.Release();
}
@@ -231,7 +286,9 @@ bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size,
return false;
}
size_ = size;
- InitializeSurface();
+ ScopedReleaseCurrent release_current(this);
+ // New surface will be initialized in SetDrawRectangle.
+ ReleaseCurrentSurface();
return true;
}
@@ -239,19 +296,16 @@ bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size,
gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers() {
{
ScopedReleaseCurrent release_current(this);
- ReleaseDrawTexture();
- visual_->SetContent(dcomp_surface_.get());
+ ReleaseDrawTexture(false);
+ DCHECK(dcomp_surface_ || swap_chain_);
+ if (dcomp_surface_)
+ visual_->SetContent(dcomp_surface_.get());
+ else
+ visual_->SetContent(swap_chain_.get());
CommitAndClearPendingOverlays();
dcomp_device_->Commit();
}
- // Force the driver to finish drawing before clearing the contents to
- // transparent, to reduce or eliminate the period of time where the contents
- // have flashed black.
- if (first_swap_) {
- glFinish();
- first_swap_ = false;
- }
child_window_.ClearInvalidContents();
return gfx::SwapResult::SWAP_ACK;
}
@@ -260,13 +314,9 @@ gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer(int x,
int y,
int width,
int height) {
- ScopedReleaseCurrent release_current(this);
- ReleaseDrawTexture();
- visual_->SetContent(dcomp_surface_.get());
- CommitAndClearPendingOverlays();
- dcomp_device_->Commit();
- child_window_.ClearInvalidContents();
- return gfx::SwapResult::SWAP_ACK;
+ // The arguments are ignored because SetDrawRectangle specified the area to
+ // be swapped.
+ return SwapBuffers();
}
gfx::VSyncProvider* DirectCompositionSurfaceWin::GetVSyncProvider() {
@@ -284,6 +334,11 @@ bool DirectCompositionSurfaceWin::ScheduleOverlayPlane(
return true;
}
+bool DirectCompositionSurfaceWin::SetEnableDCLayers(bool enable) {
+ enable_dc_layers_ = enable;
+ return true;
+}
+
bool DirectCompositionSurfaceWin::CommitAndClearPendingOverlays() {
pending_overlays_.clear();
return true;
@@ -313,13 +368,23 @@ bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) {
return true;
}
-bool DirectCompositionSurfaceWin::SupportsSetDrawRectangle() const {
+bool DirectCompositionSurfaceWin::SupportsDCLayers() const {
return true;
}
bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) {
if (draw_texture_)
return false;
+
+ DCHECK(!real_surface_);
+ ScopedReleaseCurrent release_current(this);
+
+ if ((enable_dc_layers_ && !dcomp_surface_) ||
+ (!enable_dc_layers_ && !swap_chain_)) {
+ ReleaseCurrentSurface();
+ InitializeSurface();
+ }
+
if (!gfx::Rect(size_).Contains(rectangle)) {
DLOG(ERROR) << "Draw rectangle must be contained within size of surface";
return false;
@@ -329,20 +394,24 @@ bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) {
return false;
}
- DCHECK(!real_surface_);
CHECK(!g_current_surface);
- ScopedReleaseCurrent release_current(this);
RECT rect = rectangle.ToRECT();
- POINT update_offset;
-
- HRESULT hr = dcomp_surface_->BeginDraw(
- &rect, IID_PPV_ARGS(draw_texture_.Receive()), &update_offset);
- CHECK(SUCCEEDED(hr));
+ if (dcomp_surface_) {
+ POINT update_offset;
+ HRESULT hr = dcomp_surface_->BeginDraw(
+ &rect, IID_PPV_ARGS(draw_texture_.Receive()), &update_offset);
+ draw_offset_ = gfx::Point(update_offset) - gfx::Rect(rect).origin();
+ CHECK(SUCCEEDED(hr));
+ } else {
+ HRESULT hr =
+ swap_chain_->GetBuffer(0, IID_PPV_ARGS(draw_texture_.Receive()));
+ swap_rect_ = rectangle;
+ draw_offset_ = gfx::Vector2d();
+ CHECK(SUCCEEDED(hr));
+ }
has_been_rendered_to_ = true;
- draw_offset_ = gfx::Point(update_offset) - gfx::Rect(rect).origin();
-
g_current_surface = dcomp_surface_.get();
std::vector<EGLint> pbuffer_attribs{
« no previous file with comments | « gpu/ipc/service/direct_composition_surface_win.h ('k') | gpu/ipc/service/direct_composition_surface_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698