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(
#if defined(OS_WIN)
if (!output_device_backing_)
output_device_backing_ = std::make_unique<OutputDeviceBacking>();
return std::make_unique<SoftwareOutputDeviceWin>(
output_device_backing_.get(), widget,
/*force_disable_hwnd_composited=*/true);
return std::make_unique<SoftwareOutputDeviceWin>(output_device_backing_.get(),
widget);
#elif defined(OS_MACOSX)
// 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
......
......@@ -4,8 +4,11 @@
#include "components/viz/service/display_embedder/software_output_device_win.h"
#include <algorithm>
#include "base/debug/alias.h"
#include "base/memory/shared_memory.h"
#include "base/win/windows_version.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "skia/ext/platform_canvas.h"
#include "skia/ext/skia_utils_win.h"
......@@ -14,12 +17,25 @@
#include "ui/gfx/skia_util.h"
namespace viz {
namespace {
// If a window is larger than this in bytes, don't even try to create a
// 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() {
DCHECK(devices_.empty());
......@@ -62,7 +78,7 @@ base::SharedMemory* OutputDeviceBacking::GetSharedMemory(
created_byte_size_ = expected_byte_size;
backing_.reset(new base::SharedMemory);
backing_ = std::make_unique<base::SharedMemory>();
base::debug::Alias(&expected_byte_size);
CHECK(backing_->CreateAnonymous(created_byte_size_));
return backing_.get();
......@@ -83,20 +99,13 @@ size_t OutputDeviceBacking::GetMaxByteSize() {
return max_size;
}
SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(
OutputDeviceBacking* backing,
gfx::AcceleratedWidget widget,
bool force_disable_hwnd_composited)
: hwnd_(widget),
is_hwnd_composited_(false),
backing_(backing),
in_paint_(false) {
is_hwnd_composited_ = !force_disable_hwnd_composited &&
!!::GetProp(hwnd_, ui::kWindowTranslucent);
SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(OutputDeviceBacking* backing,
HWND hwnd)
: hwnd_(hwnd),
use_layered_window_(NeedsToUseLayerWindow(hwnd)),
backing_(use_layered_window_ ? nullptr : backing) {
// Layered windows must be completely updated every time, so they can't
// share contents with other windows.
if (is_hwnd_composited_)
backing_ = nullptr;
if (backing_)
backing_->RegisterOutputDevice(this);
}
......@@ -166,7 +175,7 @@ void SoftwareOutputDeviceWin::EndPaint() {
HDC dib_dc = skia::GetNativeDrawingContext(contents_.get());
if (is_hwnd_composited_) {
if (use_layered_window_) {
RECT wr;
GetWindowRect(hwnd_, &wr);
SIZE size = {wr.right - wr.left, wr.bottom - wr.top};
......@@ -176,8 +185,8 @@ void SoftwareOutputDeviceWin::EndPaint() {
DWORD style = GetWindowLong(hwnd_, GWL_EXSTYLE);
DCHECK(!(style & WS_EX_COMPOSITED));
style |= WS_EX_LAYERED;
SetWindowLong(hwnd_, GWL_EXSTYLE, style);
if (!(style & WS_EX_LAYERED))
SetWindowLong(hwnd_, GWL_EXSTYLE, style | WS_EX_LAYERED);
::UpdateLayeredWindow(hwnd_, NULL, &position, &size, dib_dc, &zero,
RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA);
......
......@@ -41,20 +41,14 @@ class VIZ_SERVICE_EXPORT OutputDeviceBacking {
std::vector<SoftwareOutputDeviceWin*> devices_;
std::unique_ptr<base::SharedMemory> backing_;
size_t created_byte_size_;
size_t created_byte_size_ = 0;
DISALLOW_COPY_AND_ASSIGN(OutputDeviceBacking);
};
class VIZ_SERVICE_EXPORT SoftwareOutputDeviceWin : public SoftwareOutputDevice {
public:
// TODO(crbug.com/826633): Investigating if the layered window drawing
// 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(OutputDeviceBacking* backing, HWND hwnd);
~SoftwareOutputDeviceWin() override;
void Resize(const gfx::Size& viewport_pixel_size,
......@@ -66,11 +60,12 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceWin : public SoftwareOutputDevice {
void ReleaseContents();
private:
HWND hwnd_;
const HWND hwnd_;
const bool use_layered_window_;
OutputDeviceBacking* const backing_;
std::unique_ptr<SkCanvas> contents_;
bool is_hwnd_composited_;
OutputDeviceBacking* backing_;
bool in_paint_;
bool in_paint_ = false;
THREAD_CHECKER(thread_checker_);
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