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

Unified Diff: blimp/client/core/compositor/compositor_deps_provider.cc

Issue 2241623002: blimp: Move compositing, input and render widget feature to client/core. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix gn files 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
Index: blimp/client/core/compositor/compositor_deps_provider.cc
diff --git a/blimp/client/core/compositor/compositor_deps_provider.cc b/blimp/client/core/compositor/compositor_deps_provider.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d4d0558a736f3cec42d34f4f5be4f0681d5278cc
--- /dev/null
+++ b/blimp/client/core/compositor/compositor_deps_provider.cc
@@ -0,0 +1,396 @@
+// 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 "blimp/client/core/compositor/compositor_deps_provider.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
+#include "base/sys_info.h"
+#include "base/threading/thread.h"
+#include "blimp/client/core/compositor/blimp_context_provider.h"
+#include "blimp/client/core/compositor/blimp_delegating_output_surface.h"
+#include "blimp/client/core/compositor/blimp_gpu_memory_buffer_manager.h"
+#include "cc/output/buffer_to_texture_target_map.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/output_surface.h"
+#include "cc/raster/single_thread_task_graph_runner.h"
+#include "cc/trees/layer_tree_settings.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/context_support.h"
+
+#if defined(OS_ANDROID)
+#include "ui/gfx/android/device_display_info.h"
+#endif
+
+namespace blimp {
+namespace client {
+
+namespace {
+
+#if defined(OS_ANDROID)
+// The minimum valid content width in a tile. This is used to make sure the
+// width of the content on the rightmost tile isn't a tiny sliver.
+const int kMinimumTileContentWidthPixels = 64;
+#endif
+
+cc::BufferToTextureTargetMap GetDefaultBufferToTextureTargetMap() {
+ cc::BufferToTextureTargetMap image_targets;
+ for (int usage_idx = 0; usage_idx <= static_cast<int>(gfx::BufferUsage::LAST);
+ ++usage_idx) {
+ gfx::BufferUsage usage = static_cast<gfx::BufferUsage>(usage_idx);
+ for (int format_idx = 0;
+ format_idx <= static_cast<int>(gfx::BufferFormat::LAST);
+ ++format_idx) {
+ gfx::BufferFormat format = static_cast<gfx::BufferFormat>(format_idx);
+ image_targets.insert(cc::BufferToTextureTargetMap::value_type(
+ cc::BufferToTextureTargetKey(usage, format), GL_TEXTURE_2D));
+ }
+ }
+ return image_targets;
+}
+
+// Minimal implementation of cc::OutputSurface.
+class DisplayOutputSurface : public cc::OutputSurface {
+ public:
+ explicit DisplayOutputSurface(
+ scoped_refptr<BlimpContextProvider> context_provider)
+ : cc::OutputSurface(std::move(context_provider), nullptr, nullptr) {}
+
+ ~DisplayOutputSurface() override {}
+
+ // OutputSurface implementation.
+ void SwapBuffers(cc::CompositorFrame frame) override {
+ // See cc::OutputSurface::SwapBuffers() comment for details.
+ context_provider_->ContextSupport()->Swap();
+ cc::OutputSurface::PostSwapBuffersComplete();
+ }
+
+ uint32_t GetFramebufferCopyTextureFormat() override {
+ auto* gl = static_cast<BlimpContextProvider*>(context_provider());
+ return gl->GetCopyTextureInternalFormat();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DisplayOutputSurface);
+};
+
+// TaskGraphRunner that runs on a single thread. See
+// cc::SingleThreadTaskGraphRunner for details. Used by client's compositor.
+class BlimpTaskGraphRunner : public cc::SingleThreadTaskGraphRunner {
+ public:
+ BlimpTaskGraphRunner() {
+ Start("BlimpCompositorWorker",
+ base::SimpleThread::Options(base::ThreadPriority::BACKGROUND));
+ }
+
+ ~BlimpTaskGraphRunner() override { Shutdown(); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BlimpTaskGraphRunner);
+};
+
+} // namespace
+
+CompositorDepsProvider::CompositorDepsProvider(bool use_direct_rendering)
+ : use_internal_display_(use_direct_rendering) {
+ if (use_direct_rendering) {
+ gpu_memory_buffer_manager_ =
+ base::MakeUnique<BlimpGpuMemoryBufferManager>();
+ }
+}
+
+CompositorDepsProvider::~CompositorDepsProvider() = default;
+
+cc::LayerTreeSettings* CompositorDepsProvider::GetLayerTreeSettings() {
+ if (!settings_.get()) {
+ settings_ = base::MakeUnique<cc::LayerTreeSettings>();
+ GenerateLayerTreeSettings(settings_.get());
+ }
+
+ return settings_.get();
+}
+
+std::unique_ptr<cc::OutputSurface>
+CompositorDepsProvider::CreateDelegatedOutputSurface(
+ gfx::AcceleratedWidget widget) {
+ DCHECK(use_internal_display_);
+ DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
+
+ scoped_refptr<BlimpContextProvider> display_context_provider =
+ BlimpContextProvider::Create(widget, GetGpuMemoryBufferManager());
+
+ // TODO(khushalsagar): Use a worker context provider.
+ std::unique_ptr<cc::OutputSurface> display_output_surface =
+ base::MakeUnique<DisplayOutputSurface>(
+ std::move(display_context_provider));
+
+ scoped_refptr<BlimpContextProvider> compositor_context_provider =
+ BlimpContextProvider::Create(gfx::kNullAcceleratedWidget,
+ GetGpuMemoryBufferManager());
+
+ std::unique_ptr<cc::OutputSurface> delegated_output_surface =
+ base::MakeUnique<BlimpDelegatingOutputSurface>(
+ std::move(compositor_context_provider), nullptr,
+ std::move(display_output_surface), GetGpuMemoryBufferManager(),
+ GetLayerTreeSettings()->renderer_settings,
+ GetCompositorTaskRunner().get());
+
+ return delegated_output_surface;
+}
+
+cc::TaskGraphRunner* CompositorDepsProvider::GetTaskGraphRunner() {
+ if (!task_graph_runner_)
+ task_graph_runner_ = base::MakeUnique<BlimpTaskGraphRunner>();
+ return task_graph_runner_.get();
+}
+
+gpu::GpuMemoryBufferManager*
+CompositorDepsProvider::GetGpuMemoryBufferManager() {
+ if (use_internal_display_) {
+ return gpu_memory_buffer_manager_.get();
+ }
+
+ return nullptr;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+CompositorDepsProvider::GetCompositorTaskRunner() {
+ if (compositor_thread_)
+ return compositor_thread_->task_runner();
+
+ base::Thread::Options thread_options;
+#if defined(OS_ANDROID)
+ thread_options.priority = base::ThreadPriority::DISPLAY;
+#endif
+ compositor_thread_.reset(new base::Thread("Compositor"));
+ compositor_thread_->StartWithOptions(thread_options);
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ compositor_thread_->task_runner();
+ task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
+ false));
+ // TODO(dtrainor): Determine whether or not we can disallow waiting.
+
+ return task_runner;
+}
+
+void CompositorDepsProvider::GenerateLayerTreeSettings(
+ cc::LayerTreeSettings* settings) {
+ // TODO(khushalsagar): The server should selectively send only those
+ // LayerTreeSettings which should remain consistent across the server and
+ // client. Since it currently overrides all settings, ignore them.
+ // See crbug/577985.
+
+ // For web contents, layer transforms should scale up the contents of layers
+ // to keep content always crisp when possible.
+ settings->layer_transforms_should_scale_layer_contents = true;
+
+ settings->main_frame_before_activation_enabled = false;
+ settings->default_tile_size = gfx::Size(256, 256);
+ settings->gpu_rasterization_msaa_sample_count = 0;
+ settings->gpu_rasterization_forced = false;
+ settings->gpu_rasterization_enabled = false;
+ settings->can_use_lcd_text = false;
+ settings->use_distance_field_text = false;
+#if defined(OS_MACOSX)
+ settings->use_zero_copy = true;
+#else
+ settings->use_zero_copy = false;
+#endif
+ settings->enable_elastic_overscroll = false;
+ settings->image_decode_tasks_enabled = false;
+ settings->single_thread_proxy_scheduler = false;
+ settings->initial_debug_state.show_debug_borders = false;
+ settings->initial_debug_state.show_fps_counter = false;
+ settings->initial_debug_state.show_layer_animation_bounds_rects = false;
+ settings->initial_debug_state.show_paint_rects = false;
+ settings->initial_debug_state.show_property_changed_rects = false;
+ settings->initial_debug_state.show_surface_damage_rects = false;
+ settings->initial_debug_state.show_screen_space_rects = false;
+ settings->initial_debug_state.show_replica_screen_space_rects = false;
+ settings->initial_debug_state.SetRecordRenderingStats(false);
+
+#if defined(OS_ANDROID)
+ if (base::SysInfo::IsLowEndDevice())
+ settings->gpu_rasterization_enabled = false;
+ settings->using_synchronous_renderer_compositor = false;
+ settings->scrollbar_animator = cc::LayerTreeSettings::LINEAR_FADE;
+ settings->scrollbar_fade_delay_ms = 300;
+ settings->scrollbar_fade_resize_delay_ms = 2000;
+ settings->scrollbar_fade_duration_ms = 300;
+ settings->solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
+ settings->renderer_settings.highp_threshold_min = 2048;
+ settings->ignore_root_layer_flings = false;
+ bool use_low_memory_policy = base::SysInfo::IsLowEndDevice();
+ if (use_low_memory_policy) {
+ // On low-end we want to be very carefull about killing other
+ // apps. So initially we use 50% more memory to avoid flickering
+ // or raster-on-demand.
+ settings->max_memory_for_prepaint_percentage = 67;
+
+ settings->renderer_settings.preferred_tile_format = cc::RGBA_4444;
+ } else {
+ // On other devices we have increased memory excessively to avoid
+ // raster-on-demand already, so now we reserve 50% _only_ to avoid
+ // raster-on-demand, and use 50% of the memory otherwise.
+ settings->max_memory_for_prepaint_percentage = 50;
+ }
+ settings->renderer_settings.should_clear_root_render_pass = true;
+
+ // TODO(danakj): Only do this on low end devices.
+ settings->create_low_res_tiling = true;
+
+// TODO(dtrainor): Investigate whether or not we want to use an external
+// source here.
+// settings->use_external_begin_frame_source = true;
+
+#elif !defined(OS_MACOSX)
+ settings->scrollbar_animator = cc::LayerTreeSettings::LINEAR_FADE;
+ settings->solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
+ settings->scrollbar_fade_delay_ms = 500;
+ settings->scrollbar_fade_resize_delay_ms = 500;
+ settings->scrollbar_fade_duration_ms = 300;
+
+// When pinching in, only show the pinch-viewport overlay scrollbars if the
+// page scale is at least some threshold away from the minimum. i.e. don't
+// show the pinch scrollbars when at minimum scale.
+// TODO(dtrainor): Update this since https://crrev.com/1267603004 landed.
+// settings->scrollbar_show_scale_threshold = 1.05f;
+#endif
+
+ // Set the GpuMemoryPolicy.
+ cc::ManagedMemoryPolicy memory_policy = settings->memory_policy_;
+ memory_policy.bytes_limit_when_visible = 0;
+
+#if defined(OS_ANDROID)
+ // We can't query available GPU memory from the system on Android.
+ // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports
+ // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports
+ // 128MB java heap size). First we estimate physical memory using both.
+ size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB();
+ size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB();
+ size_t physical_memory_mb = 0;
+ if (dalvik_mb >= 256)
+ physical_memory_mb = dalvik_mb * 4;
+ else
+ physical_memory_mb = std::max(dalvik_mb * 4, (physical_mb * 4) / 3);
+
+ // Now we take a default of 1/8th of memory on high-memory devices,
+ // and gradually scale that back for low-memory devices (to be nicer
+ // to other apps so they don't get killed). Examples:
+ // Nexus 4/10(2GB) 256MB (normally 128MB)
+ // Droid Razr M(1GB) 114MB (normally 57MB)
+ // Galaxy Nexus(1GB) 100MB (normally 50MB)
+ // Xoom(1GB) 100MB (normally 50MB)
+ // Nexus S(low-end) 8MB (normally 8MB)
+ // Note that the compositor now uses only some of this memory for
+ // pre-painting and uses the rest only for 'emergencies'.
+ if (memory_policy.bytes_limit_when_visible == 0) {
+ // NOTE: Non-low-end devices use only 50% of these limits,
+ // except during 'emergencies' where 100% can be used.
+ if (!base::SysInfo::IsLowEndDevice()) {
+ if (physical_memory_mb >= 1536)
+ memory_policy.bytes_limit_when_visible =
+ physical_memory_mb / 8; // >192MB
+ else if (physical_memory_mb >= 1152)
+ memory_policy.bytes_limit_when_visible =
+ physical_memory_mb / 8; // >144MB
+ else if (physical_memory_mb >= 768)
+ memory_policy.bytes_limit_when_visible =
+ physical_memory_mb / 10; // >76MB
+ else
+ memory_policy.bytes_limit_when_visible =
+ physical_memory_mb / 12; // <64MB
+ } else {
+ // Low-end devices have 512MB or less memory by definition
+ // so we hard code the limit rather than relying on the heuristics
+ // above. Low-end devices use 4444 textures so we can use a lower limit.
+ memory_policy.bytes_limit_when_visible = 8;
+ }
+ memory_policy.bytes_limit_when_visible =
+ memory_policy.bytes_limit_when_visible * 1024 * 1024;
+ // Clamp the observed value to a specific range on Android.
+ memory_policy.bytes_limit_when_visible =
+ std::max(memory_policy.bytes_limit_when_visible,
+ static_cast<size_t>(8 * 1024 * 1024));
+ memory_policy.bytes_limit_when_visible =
+ std::min(memory_policy.bytes_limit_when_visible,
+ static_cast<size_t>(256 * 1024 * 1024));
+ }
+ memory_policy.priority_cutoff_when_visible =
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
+#else
+ // Ignore what the system said and give all clients the same maximum
+ // allocation on desktop platforms.
+ memory_policy.bytes_limit_when_visible = 512 * 1024 * 1024;
+ memory_policy.priority_cutoff_when_visible =
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
+#endif
+
+#if defined(OS_ANDROID)
+ // Calculate the correct raster tile size to use. Assuming a square tile.
+ DCHECK_EQ(settings->default_tile_size.width(),
+ settings->default_tile_size.height());
+
+ gfx::DeviceDisplayInfo info;
+ bool real_size_supported = true;
+ int display_width = info.GetPhysicalDisplayWidth();
+ int display_height = info.GetPhysicalDisplayHeight();
+ if (display_width == 0 || display_height == 0) {
+ real_size_supported = false;
+ display_width = info.GetDisplayWidth();
+ display_height = info.GetDisplayHeight();
+ }
+
+ int portrait_width = std::min(display_width, display_height);
+ int landscape_width = std::max(display_width, display_height);
+
+ int default_tile_size = settings->default_tile_size.width();
+ if (real_size_supported) {
+ // Maximum HD dimensions should be 768x1280
+ // Maximum FHD dimensions should be 1200x1920
+ if (portrait_width > 768 || landscape_width > 1280)
+ default_tile_size = 384;
+ if (portrait_width > 1200 || landscape_width > 1920)
+ default_tile_size = 512;
+
+ // Adjust for some resolutions that barely straddle an extra
+ // tile when in portrait mode. This helps worst case scroll/raster
+ // by not needing a full extra tile for each row.
+ int right_tile_width = ((portrait_width - 1) % default_tile_size) + 1;
+ if (right_tile_width < kMinimumTileContentWidthPixels) {
+ // Figure out the new tile count without the small edge tile.
+ int full_tile_count = portrait_width / default_tile_size;
+ DCHECK_GT(full_tile_count, 0);
+
+ // Calculate the ideal new tile width with the new tile count.
+ default_tile_size = std::ceil(static_cast<float>(portrait_width) /
+ static_cast<float>(full_tile_count));
+
+ // Round up to nearest 32 for GPU efficiency.
+ if (default_tile_size & 0x1F)
+ default_tile_size = (default_tile_size & ~0x1F) + 32;
+ }
+ } else {
+ // We don't know the exact resolution due to screen controls etc., so this
+ // just estimates the values above using tile counts.
+ int numTiles = (portrait_width * landscape_width) / (256 * 256);
+ if (numTiles > 16)
+ default_tile_size = 384;
+ if (numTiles >= 40)
+ default_tile_size = 512;
+ }
+ settings->default_tile_size.SetSize(default_tile_size, default_tile_size);
+#endif
+
+ settings->abort_commit_before_output_surface_creation = false;
+ settings_->renderer_settings.buffer_to_texture_target_map =
+ GetDefaultBufferToTextureTargetMap();
+ settings->use_output_surface_begin_frame_source = true;
+}
+
+} // namespace client
+} // namespace blimp

Powered by Google App Engine
This is Rietveld 408576698