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

Unified Diff: ui/android/delegated_frame_host_android.cc

Issue 2133873004: content: Move Surfaces related code out of RWHVA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: missed overscroll change Created 4 years, 4 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
« no previous file with comments | « ui/android/delegated_frame_host_android.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/android/delegated_frame_host_android.cc
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6e786dc9adb2d85cff2a0f62c5c29714d9189906
--- /dev/null
+++ b/ui/android/delegated_frame_host_android.cc
@@ -0,0 +1,245 @@
+// 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 "ui/android/delegated_frame_host_android.h"
+
+#include "base/logging.h"
+#include "cc/layers/solid_color_layer.h"
+#include "cc/layers/surface_layer.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/copy_output_result.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_id.h"
+#include "cc/surfaces/surface_id_allocator.h"
+#include "cc/surfaces/surface_manager.h"
+#include "ui/android/context_provider_factory.h"
+#include "ui/android/view_android.h"
+#include "ui/android/window_android_compositor.h"
+#include "ui/gfx/android/device_display_info.h"
+#include "ui/gfx/geometry/dip_util.h"
+
+namespace ui {
+
+namespace {
+
+void SatisfyCallback(cc::SurfaceManager* manager,
+ const cc::SurfaceSequence& sequence) {
+ std::vector<uint32_t> sequences;
+ sequences.push_back(sequence.sequence);
+ manager->DidSatisfySequences(sequence.client_id, &sequences);
+}
+
+void RequireCallback(cc::SurfaceManager* manager,
+ const cc::SurfaceId& id,
+ const cc::SurfaceSequence& sequence) {
+ cc::Surface* surface = manager->GetSurfaceForId(id);
+ if (!surface) {
+ LOG(ERROR) << "Attempting to require callback on nonexistent surface";
+ return;
+ }
+ surface->AddDestructionDependency(sequence);
+}
+
+scoped_refptr<cc::SurfaceLayer> CreateSurfaceLayer(
+ cc::SurfaceManager* surface_manager,
+ cc::SurfaceId surface_id,
+ const gfx::Size surface_size) {
+ // manager must outlive compositors using it.
+ scoped_refptr<cc::SurfaceLayer> layer = cc::SurfaceLayer::Create(
+ base::Bind(&SatisfyCallback, base::Unretained(surface_manager)),
+ base::Bind(&RequireCallback, base::Unretained(surface_manager)));
+ layer->SetSurfaceId(surface_id, 1.f, surface_size);
+ layer->SetBounds(surface_size);
+ layer->SetIsDrawable(true);
+ layer->SetContentsOpaque(true);
+
+ return layer;
+}
+
+void CopyOutputRequestCallback(
+ scoped_refptr<cc::Layer> readback_layer,
+ cc::CopyOutputRequest::CopyOutputRequestCallback result_callback,
+ std::unique_ptr<cc::CopyOutputResult> copy_output_result) {
+ readback_layer->RemoveFromParent();
+ result_callback.Run(std::move(copy_output_result));
+}
+
+} // namespace
+
+DelegatedFrameHostAndroid::DelegatedFrameHostAndroid(
+ ui::ViewAndroid* view,
+ SkColor background_color,
+ ReturnResourcesCallback return_resources_callback)
+ : view_(view),
+ return_resources_callback_(return_resources_callback),
+ background_layer_(cc::SolidColorLayer::Create()) {
+ DCHECK(view_);
+ DCHECK(!return_resources_callback_.is_null());
+
+ surface_manager_ =
+ ui::ContextProviderFactory::GetInstance()->GetSurfaceManager();
+ surface_id_allocator_.reset(new cc::SurfaceIdAllocator(
+ ui::ContextProviderFactory::GetInstance()->AllocateSurfaceClientId()));
+ surface_manager_->RegisterSurfaceClientId(surface_id_allocator_->client_id());
+
+ background_layer_->SetBackgroundColor(background_color);
+ view_->GetLayer()->AddChild(background_layer_);
+ UpdateBackgroundLayer();
+}
+
+DelegatedFrameHostAndroid::~DelegatedFrameHostAndroid() {
+ DestroyDelegatedContent();
+ surface_factory_.reset();
+ surface_manager_->InvalidateSurfaceClientId(
+ surface_id_allocator_->client_id());
+ background_layer_->RemoveFromParent();
+}
+
+DelegatedFrameHostAndroid::FrameData::FrameData() = default;
+
+DelegatedFrameHostAndroid::FrameData::~FrameData() = default;
+
+void DelegatedFrameHostAndroid::SubmitCompositorFrame(
+ cc::CompositorFrame frame,
+ cc::SurfaceFactory::DrawCallback draw_callback) {
+ if (!surface_factory_) {
+ surface_factory_ =
+ base::WrapUnique(new cc::SurfaceFactory(surface_manager_, this));
+ }
+
+ cc::RenderPass* root_pass =
+ frame.delegated_frame_data->render_pass_list.back().get();
+ gfx::Size surface_size = root_pass->output_rect.size();
+
+ if (!current_frame_ || surface_size != current_frame_->surface_size ||
+ current_frame_->location_bar_content_translation !=
+ frame.metadata.location_bar_content_translation ||
+ current_frame_->viewport_selection != frame.metadata.selection) {
+ DestroyDelegatedContent();
+ DCHECK(!content_layer_);
+ DCHECK(!current_frame_);
+
+ current_frame_ = base::MakeUnique<FrameData>();
+ current_frame_->surface_id = surface_id_allocator_->GenerateId();
+ surface_factory_->Create(current_frame_->surface_id);
+
+ current_frame_->surface_size = surface_size;
+ current_frame_->location_bar_content_translation =
+ frame.metadata.location_bar_content_translation;
+ current_frame_->viewport_selection = frame.metadata.selection;
+ content_layer_ =
+ CreateSurfaceLayer(surface_manager_, current_frame_->surface_id,
+ current_frame_->surface_size);
+ view_->GetLayer()->AddChild(content_layer_);
+ UpdateBackgroundLayer();
+ }
+
+ surface_factory_->SubmitCompositorFrame(current_frame_->surface_id,
+ std::move(frame), draw_callback);
+}
+
+uint32_t DelegatedFrameHostAndroid::GetSurfaceClientId() const {
+ return surface_id_allocator_->client_id();
+}
+
+void DelegatedFrameHostAndroid::RequestCopyOfSurface(
+ WindowAndroidCompositor* compositor,
+ const gfx::Rect& src_subrect_in_pixel,
+ cc::CopyOutputRequest::CopyOutputRequestCallback result_callback) {
+ DCHECK(current_frame_);
+ DCHECK(!result_callback.is_null());
+
+ scoped_refptr<cc::Layer> readback_layer =
+ CreateSurfaceLayer(surface_manager_, current_frame_->surface_id,
+ current_frame_->surface_size);
+ readback_layer->SetHideLayerAndSubtree(true);
+ compositor->AttachLayerForReadback(readback_layer);
+ std::unique_ptr<cc::CopyOutputRequest> copy_output_request =
+ cc::CopyOutputRequest::CreateRequest(base::Bind(
+ &CopyOutputRequestCallback, readback_layer, result_callback));
+
+ if (!src_subrect_in_pixel.IsEmpty())
+ copy_output_request->set_area(src_subrect_in_pixel);
+
+ surface_factory_->RequestCopyOfSurface(current_frame_->surface_id,
+ std::move(copy_output_request));
+}
+
+void DelegatedFrameHostAndroid::DestroyDelegatedContent() {
+ if (!current_frame_)
+ return;
+
+ DCHECK(surface_factory_.get());
+ DCHECK(content_layer_);
+
+ content_layer_->RemoveFromParent();
+ content_layer_ = nullptr;
+ surface_factory_->Destroy(current_frame_->surface_id);
+ current_frame_.reset();
+
+ UpdateBackgroundLayer();
+}
+
+bool DelegatedFrameHostAndroid::HasDelegatedContent() const {
+ return current_frame_.get() != nullptr;
+}
+
+void DelegatedFrameHostAndroid::OutputSurfaceChanged() {
+ DestroyDelegatedContent();
+ surface_factory_.reset();
+}
+
+void DelegatedFrameHostAndroid::UpdateBackgroundColor(SkColor color) {
+ background_layer_->SetBackgroundColor(color);
+}
+
+void DelegatedFrameHostAndroid::SetContentsOpaque(bool opaque) {
+ if (!content_layer_)
+ return;
+ content_layer_->SetContentsOpaque(opaque);
+}
+
+void DelegatedFrameHostAndroid::UpdateContainerSizeinDIP(
+ const gfx::Size& size_in_dip) {
+ container_size_in_dip_ = size_in_dip;
+ background_layer_->SetBounds(gfx::ConvertSizeToPixel(
+ gfx::DeviceDisplayInfo().GetDIPScale(), container_size_in_dip_));
+ UpdateBackgroundLayer();
+}
+
+void DelegatedFrameHostAndroid::ReturnResources(
+ const cc::ReturnedResourceArray& resources) {
+ return_resources_callback_.Run(resources);
+}
+
+void DelegatedFrameHostAndroid::SetBeginFrameSource(
+ cc::BeginFrameSource* begin_frame_source) {
+ // TODO(tansell): Hook this up.
+}
+
+void DelegatedFrameHostAndroid::UpdateBackgroundLayer() {
+ // The background layer draws in 2 cases:
+ // 1) When we don't have any content from the renderer.
+ // 2) When the bounds of the content received from the renderer does not match
+ // the desired content bounds.
+ bool background_is_drawable = false;
+
+ if (current_frame_) {
+ float device_scale_factor = gfx::DeviceDisplayInfo().GetDIPScale();
+ gfx::Size content_size_in_dip = gfx::ConvertSizeToDIP(
+ device_scale_factor, current_frame_->surface_size);
+ content_size_in_dip.set_height(
+ content_size_in_dip.height() +
+ current_frame_->location_bar_content_translation.y());
+ background_is_drawable =
+ content_size_in_dip.width() < container_size_in_dip_.width() ||
+ content_size_in_dip.height() < container_size_in_dip_.height();
+ } else {
+ background_is_drawable = true;
+ }
+
+ background_layer_->SetIsDrawable(background_is_drawable);
+}
+
+} // namespace ui
« no previous file with comments | « ui/android/delegated_frame_host_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698