summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc
blob: f07c3a9c77f0b65d7e4172b1b74b6161d8f43fdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/platform/graphics/surface_layer_bridge.h"

#include "base/feature_list.h"
#include "cc/layers/layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/surface_layer.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "media/base/media_switches.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_layer_tree_view.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "ui/gfx/geometry/size.h"

namespace blink {

SurfaceLayerBridge::SurfaceLayerBridge(WebLayerTreeView* layer_tree_view,
                                       WebSurfaceLayerBridgeObserver* observer)
    : observer_(observer),
      binding_(this),
      frame_sink_id_(Platform::Current()->GenerateFrameSinkId()),
      parent_frame_sink_id_(layer_tree_view ? layer_tree_view->GetFrameSinkId()
                                            : viz::FrameSinkId()) {
  mojom::blink::EmbeddedFrameSinkProviderPtr provider;
  Platform::Current()->GetInterfaceProvider()->GetInterface(
      mojo::MakeRequest(&provider));
  // TODO(xlai): Ensure OffscreenCanvas commit() is still functional when a
  // frame-less HTML canvas's document is reparenting under another frame.
  // See crbug.com/683172.
  blink::mojom::blink::EmbeddedFrameSinkClientPtr client;
  binding_.Bind(mojo::MakeRequest(&client));
  provider->RegisterEmbeddedFrameSink(parent_frame_sink_id_, frame_sink_id_,
                                      std::move(client));
}

SurfaceLayerBridge::~SurfaceLayerBridge() {
  observer_ = nullptr;
}

void SurfaceLayerBridge::ClearSurfaceId() {
  current_surface_id_ = viz::SurfaceId();
  cc::SurfaceLayer* surface_layer =
      static_cast<cc::SurfaceLayer*>(cc_layer_.get());

  if (!surface_layer)
    return;

  // We reset the Ids if we lose the context_provider (case: GPU process ended)
  // If we destroyed the surface_layer before that point, we need not update
  // the ids.
  surface_layer->SetPrimarySurfaceId(viz::SurfaceId(),
                                     cc::DeadlinePolicy::UseDefaultDeadline());
  surface_layer->SetFallbackSurfaceId(viz::SurfaceId());
}

void SurfaceLayerBridge::CreateSolidColorLayer() {
  cc_layer_ = cc::SolidColorLayer::Create();
  cc_layer_->SetBackgroundColor(SK_ColorTRANSPARENT);

  if (observer_)
    observer_->RegisterContentsLayer(cc_layer_.get());
}

void SurfaceLayerBridge::OnFirstSurfaceActivation(
    const viz::SurfaceInfo& surface_info) {
  if (!current_surface_id_.is_valid() && surface_info.is_valid()) {
    // First time a SurfaceId is received.
    current_surface_id_ = surface_info.id();
    if (cc_layer_) {
      if (observer_)
        observer_->UnregisterContentsLayer(cc_layer_.get());
      cc_layer_->RemoveFromParent();
    }

    scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create();
    surface_layer->SetPrimarySurfaceId(
        surface_info.id(), cc::DeadlinePolicy::UseDefaultDeadline());
    surface_layer->SetFallbackSurfaceId(surface_info.id());
    surface_layer->SetStretchContentToFillBounds(true);
    surface_layer->SetIsDrawable(true);
    cc_layer_ = surface_layer;

    if (observer_)
      observer_->RegisterContentsLayer(cc_layer_.get());
  } else if (current_surface_id_ != surface_info.id()) {
    // A different SurfaceId is received, prompting change to existing
    // SurfaceLayer.
    current_surface_id_ = surface_info.id();
    cc::SurfaceLayer* surface_layer =
        static_cast<cc::SurfaceLayer*>(cc_layer_.get());
    surface_layer->SetPrimarySurfaceId(
        surface_info.id(), cc::DeadlinePolicy::UseDefaultDeadline());
    surface_layer->SetFallbackSurfaceId(surface_info.id());
  }

  if (observer_) {
    observer_->OnWebLayerUpdated();
    observer_->OnSurfaceIdUpdated(surface_info.id());
  }

  cc_layer_->SetBounds(surface_info.size_in_pixels());
}

}  // namespace blink