Skip to content

Commit

Permalink
gpu: win: Avoid unconditionally QI to IDCompositionVisual3
Browse files Browse the repository at this point in the history
In crrev.com/c/4599273 we change DCLayerTree to use
IDCompositionVisual3 instead of IDCompositionVisual2. Since
IDCompositionDevice3 doesn't have a
CreateVisual(IDCompositionVisual3**) overload, we need to call
CreateVisual(IDCompositionVisual2**) and QueryInterface to
IDCompositionVisual3. This should be valid as long as a
IDCompositionDevice3 was used to create the visual.

However, we noticed crashes on our QI call, so this change moves the
cast to be optional only when the opacity property on a overlay is
non-default. This will not happen until delegated compositing is
enabled.

(cherry picked from commit 586b0bd)

Bug: 1455666
Change-Id: Ib76e40d3d8526a5936bb1dbacf58763b79db174d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4626863
Commit-Queue: Michael Tang <tangm@microsoft.com>
Reviewed-by: Maggie Chen <magchen@chromium.org>
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1160933}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4633565
Reviewed-by: Daniel Yip <danielyip@google.com>
Auto-Submit: Daniel Yip <danielyip@google.com>
Owners-Override: Daniel Yip <danielyip@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5845@{#15}
Cr-Branched-From: 5a5dff6-refs/heads/main@{#1160321}
  • Loading branch information
tangm-msft authored and Chromium LUCI CQ committed Jun 22, 2023
1 parent d058b15 commit f1dc50d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 37 deletions.
48 changes: 21 additions & 27 deletions ui/gl/dc_layer_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,7 @@ bool DCLayerTree::Initialize(HWND window) {
return false;
}

Microsoft::WRL::ComPtr<IDCompositionVisual2> dcomp_root_visual;
hr = dcomp_device_->CreateVisual(&dcomp_root_visual);
CHECK_EQ(hr, S_OK);
hr = dcomp_root_visual.As(&dcomp_root_visual_);
hr = dcomp_device_->CreateVisual(&dcomp_root_visual_);
CHECK_EQ(hr, S_OK);

dcomp_target_->SetRoot(dcomp_root_visual_.Get());
Expand Down Expand Up @@ -234,28 +231,13 @@ bool DCLayerTree::VisualTree::VisualSubtree::Update(
CHECK(!transform_visual_);
CHECK(!content_visual_);

Microsoft::WRL::ComPtr<IDCompositionVisual2> clip_visual;
hr = dcomp_device->CreateVisual(&clip_visual);
CHECK_EQ(hr, S_OK);
hr = clip_visual.As(&clip_visual_);
CHECK_EQ(hr, S_OK);

Microsoft::WRL::ComPtr<IDCompositionVisual2> rounded_corners_visual;
hr = dcomp_device->CreateVisual(&rounded_corners_visual);
CHECK_EQ(hr, S_OK);
hr = rounded_corners_visual.As(&rounded_corners_visual_);
CHECK_EQ(hr, S_OK);

Microsoft::WRL::ComPtr<IDCompositionVisual2> transform_visual;
hr = dcomp_device->CreateVisual(&transform_visual);
hr = dcomp_device->CreateVisual(&clip_visual_);
CHECK_EQ(hr, S_OK);
hr = transform_visual.As(&transform_visual_);
hr = dcomp_device->CreateVisual(&rounded_corners_visual_);
CHECK_EQ(hr, S_OK);

Microsoft::WRL::ComPtr<IDCompositionVisual2> content_visual;
hr = dcomp_device->CreateVisual(&content_visual);
hr = dcomp_device->CreateVisual(&transform_visual_);
CHECK_EQ(hr, S_OK);
hr = content_visual.As(&content_visual_);
hr = dcomp_device->CreateVisual(&content_visual_);
CHECK_EQ(hr, S_OK);

hr = clip_visual_->AddVisual(rounded_corners_visual_.Get(), FALSE, nullptr);
Expand Down Expand Up @@ -294,16 +276,28 @@ bool DCLayerTree::VisualTree::VisualSubtree::Update(
opacity_ = opacity;
needs_commit = true;

// |IDCompositionVisual3| should be available since Windows 8.1, but we
// noticed crashes due to unconditionally casting to the interface on very
// early versions of Windows 10. Here, we only attempt the cast when the
// opacity changes, which should only happen for features that we don't
// intend to run unconditionally. If this cast fails, we may need to exclude
// some Windows versions from these features.
// See: https://crbug.com/1455666
Microsoft::WRL::ComPtr<IDCompositionVisual3> clip_visual_opacity;
hr = clip_visual_.As(&clip_visual_opacity);
CHECK_EQ(hr, S_OK);
CHECK(clip_visual_opacity);

if (opacity_ != 1) {
hr = clip_visual_->SetOpacity(opacity_);
hr = clip_visual_opacity->SetOpacity(opacity_);
CHECK_EQ(hr, S_OK);

// Let all of this subtree's visuals blend as one, instead of
// individually
hr = clip_visual_->SetOpacityMode(DCOMPOSITION_OPACITY_MODE_LAYER);
CHECK_EQ(hr, S_OK);
} else {
hr = clip_visual_->SetOpacity(1.0);
hr = clip_visual_opacity->SetOpacity(1.0);
CHECK_EQ(hr, S_OK);
hr = clip_visual_->SetOpacityMode(DCOMPOSITION_OPACITY_MODE_MULTIPLY);
CHECK_EQ(hr, S_OK);
Expand Down Expand Up @@ -543,7 +537,7 @@ bool DCLayerTree::VisualTree::UpdateTree(
}

// Visual for root surface. Cache it to add DelegatedInk visual if needed.
Microsoft::WRL::ComPtr<IDCompositionVisual3> root_surface_visual;
Microsoft::WRL::ComPtr<IDCompositionVisual2> root_surface_visual;
bool needs_commit = false;
std::vector<std::unique_ptr<VisualSubtree>> visual_subtrees;
visual_subtrees.resize(overlays.size());
Expand Down Expand Up @@ -863,7 +857,7 @@ bool DCLayerTree::InitializeInkRenderer() {
}

void DCLayerTree::AddDelegatedInkVisualToTreeIfNeeded(
IDCompositionVisual3* root_surface_visual) {
IDCompositionVisual2* root_surface_visual) {
// Only add the ink visual to the tree if it has already been initialized.
// It will only have been initialized if delegated ink has been used, so
// this ensures the visual is only added when it is needed. The ink renderer
Expand Down
20 changes: 10 additions & 10 deletions ui/gl/dc_layer_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class DCLayerTree {
size_t GetDcompLayerCountForTesting() const {
return visual_tree_ ? visual_tree_->GetDcompLayerCountForTesting() : 0;
}
IDCompositionVisual3* GetContentVisualForTesting(size_t index) const {
IDCompositionVisual2* GetContentVisualForTesting(size_t index) const {
return visual_tree_ ? visual_tree_->GetContentVisualForTesting(index)
: nullptr;
}
Expand Down Expand Up @@ -183,7 +183,7 @@ class DCLayerTree {
size_t GetDcompLayerCountForTesting() const {
return visual_subtrees_.size();
}
IDCompositionVisual3* GetContentVisualForTesting(size_t index) const {
IDCompositionVisual2* GetContentVisualForTesting(size_t index) const {
return visual_subtrees_[index]->content_visual();
}
// Returns true if the tree is optimized.
Expand Down Expand Up @@ -218,10 +218,10 @@ class DCLayerTree {
float opacity,
const absl::optional<gfx::Rect>& clip_rect_in_root);

IDCompositionVisual3* container_visual() const {
IDCompositionVisual2* container_visual() const {
return clip_visual_.Get();
}
IDCompositionVisual3* content_visual() const {
IDCompositionVisual2* content_visual() const {
return content_visual_.Get();
}
IUnknown* dcomp_visual_content() const {
Expand All @@ -237,21 +237,21 @@ class DCLayerTree {
private:
// The root of this subtree. In root space and contains the clip rect and
// controls subtree opacity.
Microsoft::WRL::ComPtr<IDCompositionVisual3> clip_visual_;
Microsoft::WRL::ComPtr<IDCompositionVisual2> clip_visual_;
// In root space and contains the rounded rectangle clip. This is separate
// from |clip_visual_| since an overlay layer can have both a rectangular
// and a rounded rectangular clip rects.
Microsoft::WRL::ComPtr<IDCompositionVisual3> rounded_corners_visual_;
Microsoft::WRL::ComPtr<IDCompositionVisual2> rounded_corners_visual_;
// The child of |clip_visual_|, transforms its children from quad to root
// space. This visual exists because |offset_| is in quad space, so it
// must be affected by |transform_|. They cannot be on the same visual
// since |IDCompositionVisual::SetTransform| and
// |IDCompositionVisual::SetOffset[XY]| are applied in the opposite order
// than we want.
Microsoft::WRL::ComPtr<IDCompositionVisual3> transform_visual_;
Microsoft::WRL::ComPtr<IDCompositionVisual2> transform_visual_;
// The child of |transform_visual_|. In quad space, holds
// |dcomp_visual_content_|.
Microsoft::WRL::ComPtr<IDCompositionVisual3> content_visual_;
Microsoft::WRL::ComPtr<IDCompositionVisual2> content_visual_;

// The content to be placed at the leaf of the visual subtree. Either an
// IDCompositionSurface or an IDXGISwapChain.
Expand Down Expand Up @@ -329,7 +329,7 @@ class DCLayerTree {
// delegated ink API is used. After that, it can also be added anytime the
// visual tree is rebuilt.
void AddDelegatedInkVisualToTreeIfNeeded(
IDCompositionVisual3* root_surface_visual);
IDCompositionVisual2* root_surface_visual);

// The ink renderer must be initialized before an OS API is used in order to
// set up the delegated ink visual and delegated ink trail object.
Expand Down Expand Up @@ -374,7 +374,7 @@ class DCLayerTree {
Microsoft::WRL::ComPtr<IDCompositionSurface> root_dcomp_surface_;

// Root direct composition visual for window dcomp target.
Microsoft::WRL::ComPtr<IDCompositionVisual3> dcomp_root_visual_;
Microsoft::WRL::ComPtr<IDCompositionVisual2> dcomp_root_visual_;

// List of pending overlay layers from ScheduleDCLayer().
std::vector<std::unique_ptr<DCLayerOverlayParams>> pending_overlays_;
Expand Down

0 comments on commit f1dc50d

Please sign in to comment.