Index: content/browser/renderer_host/delegated_frame_host_android.cc |
diff --git a/content/browser/renderer_host/delegated_frame_host_android.cc b/content/browser/renderer_host/delegated_frame_host_android.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a06f875e6b4eb531161d6ecb9172df38cc7dde7b |
--- /dev/null |
+++ b/content/browser/renderer_host/delegated_frame_host_android.cc |
@@ -0,0 +1,132 @@ |
+// 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 "content/browser/renderer_host/delegated_frame_host_android.h" |
+ |
+#include "base/logging.h" |
+#include "cc/layers/surface_layer.h" |
+#include "cc/output/compositor_frame.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" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+void SatisfyCallback(cc::SurfaceManager* manager, |
+ const cc::SurfaceSequence& sequence) { |
+ std::vector<uint32_t> sequences; |
+ sequences.push_back(sequence.sequence); |
+ manager->DidSatisfySequences(sequence.id_namespace, &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); |
+} |
+ |
+} // namespace |
+ |
+DelegatedFrameHostAndroid::DelegatedFrameHostAndroid( |
+ cc::SurfaceManager* surface_manager, |
+ std::unique_ptr<cc::SurfaceIdAllocator> surface_id_allocator, |
+ DelegatedFrameHostAndroidClient* client) |
+ : surface_manager_(surface_manager), |
+ surface_id_allocator_(std::move(surface_id_allocator)), |
+ client_(client) {} |
+ |
+DelegatedFrameHostAndroid::~DelegatedFrameHostAndroid() { |
+ DestroyDelegatedContent(); |
+ surface_factory_.reset(); |
+} |
+ |
+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 texture_size_in_layer = root_pass->output_rect.size(); |
+ |
+ if (surface_id_.is_null() || texture_size_in_layer != current_surface_size_ || |
+ location_bar_content_translation_ != |
+ frame.metadata.location_bar_content_translation || |
+ current_viewport_selection_ != frame.metadata.selection) { |
+ client_->DetachSurfaceLayer(); |
+ if (!surface_id_.is_null()) |
+ surface_factory_->Destroy(surface_id_); |
+ surface_id_ = surface_id_allocator_->GenerateId(); |
+ surface_factory_->Create(surface_id_); |
+ |
+ current_surface_size_ = texture_size_in_layer; |
+ location_bar_content_translation_ = |
+ frame.metadata.location_bar_content_translation; |
+ current_viewport_selection_ = frame.metadata.selection; |
+ client_->AttachSurfaceLayer(std::move(CreateSurfaceLayer())); |
+ } |
+ |
+ surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame), |
+ draw_callback); |
+} |
+ |
+bool DelegatedFrameHostAndroid::HasDelegatedContent() const { |
+ return !surface_id_.is_null(); |
+} |
+ |
+void DelegatedFrameHostAndroid::DestroyDelegatedContent() { |
+ if (!HasDelegatedContent()) |
+ return; |
+ |
+ DCHECK(surface_factory_.get()); |
+ |
+ client_->DetachSurfaceLayer(); |
+ surface_factory_->Destroy(surface_id_); |
+ surface_id_ = cc::SurfaceId(); |
+} |
+ |
+uint32_t DelegatedFrameHostAndroid::GetSurfaceIdNamespace() { |
+ if (surface_id_allocator_) |
+ return surface_id_allocator_->id_namespace(); |
+ return 0; |
+} |
+ |
+void DelegatedFrameHostAndroid::ReturnResources( |
+ const cc::ReturnedResourceArray& resources) { |
+ client_->ReturnCompositorFrameResources(resources); |
+} |
+ |
+void DelegatedFrameHostAndroid::SetBeginFrameSource( |
+ cc::BeginFrameSource* begin_frame_source) { |
+ // TODO(tansell): Hook this up. |
+} |
+ |
+scoped_refptr<cc::SurfaceLayer> |
+DelegatedFrameHostAndroid::CreateSurfaceLayer() { |
+ DCHECK(!surface_id_.is_null()); |
+ |
+ // manager must outlive compositors using it. |
+ scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create( |
+ base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), |
+ base::Bind(&RequireCallback, base::Unretained(surface_manager_))); |
+ surface_layer->SetSurfaceId(surface_id_, 1.f, current_surface_size_); |
+ surface_layer->SetBounds(current_surface_size_); |
+ surface_layer->SetIsDrawable(true); |
+ surface_layer->SetContentsOpaque(true); |
+ |
+ return surface_layer; |
+} |
+ |
+} // namespace content |