Commit 2ad2b06d authored by kylechar's avatar kylechar Committed by Commit Bot

Don't use layered windows on Windows 8+.

This CL stops using layered windows on Windows 8 and higher. Layered
window provide a way to add transparency effects on HWNDs. This is a
legacy API and DWM natively supports transparency. DWM will always be
there on Windows 8 and higher, so layered windows aren't needed.

Layered windows present GPU sandbox problems with OOP-D. Layered windows
also can't be partial updated, the entire window needs to be updated at
once.

Bug: 826633
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel
Change-Id: I6d0ab96392ee603b3b6ed680114f9e8a43c6134f
Reviewed-on: https://chromium-review.googlesource.com/1024874
Commit-Queue: kylechar <kylechar@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556059}
parent 631f3b47
...@@ -212,9 +212,8 @@ GpuDisplayProvider::CreateSoftwareOutputDeviceForPlatform( ...@@ -212,9 +212,8 @@ GpuDisplayProvider::CreateSoftwareOutputDeviceForPlatform(
#if defined(OS_WIN) #if defined(OS_WIN)
if (!output_device_backing_) if (!output_device_backing_)
output_device_backing_ = std::make_unique<OutputDeviceBacking>(); output_device_backing_ = std::make_unique<OutputDeviceBacking>();
return std::make_unique<SoftwareOutputDeviceWin>( return std::make_unique<SoftwareOutputDeviceWin>(output_device_backing_.get(),
output_device_backing_.get(), widget, widget);
/*force_disable_hwnd_composited=*/true);
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
// TODO(crbug.com/730660): What do we do to get something we can draw to? Can // TODO(crbug.com/730660): What do we do to get something we can draw to? Can
// we use an IO surface? Can we use CA layers and overlays like we do for gpu // we use an IO surface? Can we use CA layers and overlays like we do for gpu
......
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
#include "components/viz/service/display_embedder/software_output_device_win.h" #include "components/viz/service/display_embedder/software_output_device_win.h"
#include <algorithm>
#include "base/debug/alias.h" #include "base/debug/alias.h"
#include "base/memory/shared_memory.h" #include "base/memory/shared_memory.h"
#include "base/win/windows_version.h"
#include "components/viz/common/resources/resource_sizes.h" #include "components/viz/common/resources/resource_sizes.h"
#include "skia/ext/platform_canvas.h" #include "skia/ext/platform_canvas.h"
#include "skia/ext/skia_utils_win.h" #include "skia/ext/skia_utils_win.h"
...@@ -14,12 +17,25 @@ ...@@ -14,12 +17,25 @@
#include "ui/gfx/skia_util.h" #include "ui/gfx/skia_util.h"
namespace viz { namespace viz {
namespace {
// If a window is larger than this in bytes, don't even try to create a // If a window is larger than this in bytes, don't even try to create a
// backing bitmap for it. // backing bitmap for it.
static const size_t kMaxBitmapSizeBytes = 4 * (16384 * 8192); constexpr size_t kMaxBitmapSizeBytes = 4 * (16384 * 8192);
bool NeedsToUseLayerWindow(HWND hwnd) {
// Layered windows are a legacy way of supporting transparency for HWNDs. With
// Desktop Window Manager (DWM) HWNDs support transparency natively. DWM is
// always enabled on Windows 8 and later. However, for Windows 7 (and earlier)
// DWM might be disabled and layered windows are necessary for HWNDs with
// transparency.
return base::win::GetVersion() <= base::win::VERSION_WIN7 &&
GetProp(hwnd, ui::kWindowTranslucent);
}
} // namespace
OutputDeviceBacking::OutputDeviceBacking() : created_byte_size_(0) {} OutputDeviceBacking::OutputDeviceBacking() = default;
OutputDeviceBacking::~OutputDeviceBacking() { OutputDeviceBacking::~OutputDeviceBacking() {
DCHECK(devices_.empty()); DCHECK(devices_.empty());
...@@ -62,7 +78,7 @@ base::SharedMemory* OutputDeviceBacking::GetSharedMemory( ...@@ -62,7 +78,7 @@ base::SharedMemory* OutputDeviceBacking::GetSharedMemory(
created_byte_size_ = expected_byte_size; created_byte_size_ = expected_byte_size;
backing_.reset(new base::SharedMemory); backing_ = std::make_unique<base::SharedMemory>();
base::debug::Alias(&expected_byte_size); base::debug::Alias(&expected_byte_size);
CHECK(backing_->CreateAnonymous(created_byte_size_)); CHECK(backing_->CreateAnonymous(created_byte_size_));
return backing_.get(); return backing_.get();
...@@ -83,20 +99,13 @@ size_t OutputDeviceBacking::GetMaxByteSize() { ...@@ -83,20 +99,13 @@ size_t OutputDeviceBacking::GetMaxByteSize() {
return max_size; return max_size;
} }
SoftwareOutputDeviceWin::SoftwareOutputDeviceWin( SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(OutputDeviceBacking* backing,
OutputDeviceBacking* backing, HWND hwnd)
gfx::AcceleratedWidget widget, : hwnd_(hwnd),
bool force_disable_hwnd_composited) use_layered_window_(NeedsToUseLayerWindow(hwnd)),
: hwnd_(widget), backing_(use_layered_window_ ? nullptr : backing) {
is_hwnd_composited_(false),
backing_(backing),
in_paint_(false) {
is_hwnd_composited_ = !force_disable_hwnd_composited &&
!!::GetProp(hwnd_, ui::kWindowTranslucent);
// Layered windows must be completely updated every time, so they can't // Layered windows must be completely updated every time, so they can't
// share contents with other windows. // share contents with other windows.
if (is_hwnd_composited_)
backing_ = nullptr;
if (backing_) if (backing_)
backing_->RegisterOutputDevice(this); backing_->RegisterOutputDevice(this);
} }
...@@ -166,7 +175,7 @@ void SoftwareOutputDeviceWin::EndPaint() { ...@@ -166,7 +175,7 @@ void SoftwareOutputDeviceWin::EndPaint() {
HDC dib_dc = skia::GetNativeDrawingContext(contents_.get()); HDC dib_dc = skia::GetNativeDrawingContext(contents_.get());
if (is_hwnd_composited_) { if (use_layered_window_) {
RECT wr; RECT wr;
GetWindowRect(hwnd_, &wr); GetWindowRect(hwnd_, &wr);
SIZE size = {wr.right - wr.left, wr.bottom - wr.top}; SIZE size = {wr.right - wr.left, wr.bottom - wr.top};
...@@ -176,8 +185,8 @@ void SoftwareOutputDeviceWin::EndPaint() { ...@@ -176,8 +185,8 @@ void SoftwareOutputDeviceWin::EndPaint() {
DWORD style = GetWindowLong(hwnd_, GWL_EXSTYLE); DWORD style = GetWindowLong(hwnd_, GWL_EXSTYLE);
DCHECK(!(style & WS_EX_COMPOSITED)); DCHECK(!(style & WS_EX_COMPOSITED));
style |= WS_EX_LAYERED; if (!(style & WS_EX_LAYERED))
SetWindowLong(hwnd_, GWL_EXSTYLE, style); SetWindowLong(hwnd_, GWL_EXSTYLE, style | WS_EX_LAYERED);
::UpdateLayeredWindow(hwnd_, NULL, &position, &size, dib_dc, &zero, ::UpdateLayeredWindow(hwnd_, NULL, &position, &size, dib_dc, &zero,
RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA);
......
...@@ -41,20 +41,14 @@ class VIZ_SERVICE_EXPORT OutputDeviceBacking { ...@@ -41,20 +41,14 @@ class VIZ_SERVICE_EXPORT OutputDeviceBacking {
std::vector<SoftwareOutputDeviceWin*> devices_; std::vector<SoftwareOutputDeviceWin*> devices_;
std::unique_ptr<base::SharedMemory> backing_; std::unique_ptr<base::SharedMemory> backing_;
size_t created_byte_size_; size_t created_byte_size_ = 0;
DISALLOW_COPY_AND_ASSIGN(OutputDeviceBacking); DISALLOW_COPY_AND_ASSIGN(OutputDeviceBacking);
}; };
class VIZ_SERVICE_EXPORT SoftwareOutputDeviceWin : public SoftwareOutputDevice { class VIZ_SERVICE_EXPORT SoftwareOutputDeviceWin : public SoftwareOutputDevice {
public: public:
// TODO(crbug.com/826633): Investigating if the layered window drawing SoftwareOutputDeviceWin(OutputDeviceBacking* backing, HWND hwnd);
// path is necessary then remove |force_disable_hwnd_composited|. This is only
// used with --enable-features=VizDisplayCompositor where
// UpdateLayeredWindow() call is blocked by GPU sandbox.
SoftwareOutputDeviceWin(OutputDeviceBacking* backing,
gfx::AcceleratedWidget widget,
bool force_disable_hwnd_composited = false);
~SoftwareOutputDeviceWin() override; ~SoftwareOutputDeviceWin() override;
void Resize(const gfx::Size& viewport_pixel_size, void Resize(const gfx::Size& viewport_pixel_size,
...@@ -66,11 +60,12 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceWin : public SoftwareOutputDevice { ...@@ -66,11 +60,12 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceWin : public SoftwareOutputDevice {
void ReleaseContents(); void ReleaseContents();
private: private:
HWND hwnd_; const HWND hwnd_;
const bool use_layered_window_;
OutputDeviceBacking* const backing_;
std::unique_ptr<SkCanvas> contents_; std::unique_ptr<SkCanvas> contents_;
bool is_hwnd_composited_; bool in_paint_ = false;
OutputDeviceBacking* backing_;
bool in_paint_;
THREAD_CHECKER(thread_checker_); THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceWin); DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceWin);
......
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