// Copyright 2011 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. #ifndef CC_TREES_LAYER_TREE_HOST_H_ #define CC_TREES_LAYER_TREE_HOST_H_ #include #include #include "base/basictypes.h" #include "base/cancelable_callback.h" #include "base/containers/hash_tables.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time.h" #include "cc/animation/animation_events.h" #include "cc/base/cc_export.h" #include "cc/base/scoped_ptr_vector.h" #include "cc/input/input_handler.h" #include "cc/input/scrollbar.h" #include "cc/input/top_controls_state.h" #include "cc/layers/layer_lists.h" #include "cc/output/output_surface.h" #include "cc/scheduler/rate_limiter.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/occlusion_tracker.h" #include "cc/trees/proxy.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPicture.h" #include "ui/base/latency_info.h" #include "ui/gfx/rect.h" namespace WebKit { class WebGraphicsContext3D; } #if defined(COMPILER_GCC) namespace BASE_HASH_NAMESPACE { template <> struct hash { size_t operator()(WebKit::WebGraphicsContext3D* ptr) const { return hash()(reinterpret_cast(ptr)); } }; } // namespace BASE_HASH_NAMESPACE #endif // COMPILER namespace cc { class AnimationRegistrar; class HeadsUpDisplayLayer; class Layer; class LayerTreeHostImpl; class LayerTreeHostImplClient; class PrioritizedResourceManager; class PrioritizedResource; class Region; class RenderingStatsInstrumentation; class ResourceProvider; class ResourceUpdateQueue; class TopControlsManager; struct RenderingStats; struct ScrollAndScaleSet; // Provides information on an Impl's rendering capabilities back to the // LayerTreeHost. struct CC_EXPORT RendererCapabilities { RendererCapabilities(); ~RendererCapabilities(); unsigned best_texture_format; bool using_partial_swap; bool using_set_visibility; bool using_gpu_memory_manager; bool using_egl_image; bool allow_partial_texture_updates; bool using_offscreen_context3d; int max_texture_size; bool avoid_pow2_textures; bool using_map_image; }; class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { public: static scoped_ptr Create(LayerTreeHostClient* client, const LayerTreeSettings& settings, scoped_ptr impl_thread); virtual ~LayerTreeHost(); void SetLayerTreeHostClientReady(); // Returns true if any LayerTreeHost is alive. static bool AnyLayerTreeHostInstanceExists(); void set_needs_filter_context() { needs_filter_context_ = true; } bool needs_offscreen_context() const { return needs_filter_context_; } // LayerTreeHost interface to Proxy. void WillBeginFrame() { client_->WillBeginFrame(); } void DidBeginFrame(); void UpdateClientAnimations(base::TimeTicks monotonic_frame_begin_time); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); void DidStopFlinging(); void Layout(); void BeginCommitOnImplThread(LayerTreeHostImpl* host_impl); void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete(); scoped_ptr CreateOutputSurface(); virtual scoped_ptr CreateLayerTreeHostImpl( LayerTreeHostImplClient* client); void DidLoseOutputSurface(); bool output_surface_lost() const { return output_surface_lost_; } enum CreateResult { CreateSucceeded, CreateFailedButTryAgain, CreateFailedAndGaveUp, }; CreateResult OnCreateAndInitializeOutputSurfaceAttempted(bool success); void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); } void DidCompleteSwapBuffers() { client_->DidCompleteSwapBuffers(); } void DeleteContentsTexturesOnImplThread(ResourceProvider* resource_provider); virtual void AcquireLayerTextures(); // Returns false if we should abort this frame due to initialization failure. bool InitializeOutputSurfaceIfNeeded(); void UpdateLayers(ResourceUpdateQueue* queue, size_t contents_memory_limit_bytes); LayerTreeHostClient* client() { return client_; } const base::WeakPtr& GetInputHandler() { return input_handler_weak_ptr_; } void Composite(base::TimeTicks frame_begin_time); // Only used when compositing on the main thread. void ScheduleComposite(); // Composites and attempts to read back the result into the provided // buffer. If it wasn't possible, e.g. due to context lost, will return // false. bool CompositeAndReadback(void* pixels, gfx::Rect rect_in_device_viewport); void FinishAllRendering(); void SetDeferCommits(bool defer_commits); // Test only hook virtual void DidDeferCommit(); int commit_number() const { return commit_number_; } void SetNeedsDisplayOnAllLayers(); void CollectRenderingStats(RenderingStats* stats) const; RenderingStatsInstrumentation* rendering_stats_instrumentation() const { return rendering_stats_instrumentation_.get(); } const RendererCapabilities& GetRendererCapabilities() const; void SetNeedsAnimate(); virtual void SetNeedsCommit(); virtual void SetNeedsFullTreeSync(); void SetNeedsRedraw(); void SetNeedsRedrawRect(gfx::Rect damage_rect); bool CommitRequested() const; void SetAnimationEvents(scoped_ptr events, base::Time wall_clock_time); void SetRootLayer(scoped_refptr root_layer); Layer* root_layer() { return root_layer_.get(); } const Layer* root_layer() const { return root_layer_.get(); } const LayerTreeSettings& settings() const { return settings_; } void SetDebugState(const LayerTreeDebugState& debug_state); const LayerTreeDebugState& debug_state() const { return debug_state_; } void SetViewportSize(gfx::Size device_viewport_size); void SetOverdrawBottomHeight(float overdraw_bottom_height); gfx::Size device_viewport_size() const { return device_viewport_size_; } float overdraw_bottom_height() const { return overdraw_bottom_height_; } void SetPageScaleFactorAndLimits(float page_scale_factor, float min_page_scale_factor, float max_page_scale_factor); float page_scale_factor() const { return page_scale_factor_; } SkColor background_color() const { return background_color_; } void set_background_color(SkColor color) { background_color_ = color; } void set_has_transparent_background(bool transparent) { has_transparent_background_ = transparent; } PrioritizedResourceManager* contents_texture_manager() const { return contents_texture_manager_.get(); } void SetVisible(bool visible); bool visible() const { return visible_; } void StartPageScaleAnimation(gfx::Vector2d target_offset, bool use_anchor, float scale, base::TimeDelta duration); void ApplyScrollAndScale(const ScrollAndScaleSet& info); void SetImplTransform(const gfx::Transform& transform); void SetLatencyInfo(const ui::LatencyInfo& latency_info); void StartRateLimiter(WebKit::WebGraphicsContext3D* context3d); void StopRateLimiter(WebKit::WebGraphicsContext3D* context3d); // RateLimiterClient implementation. virtual void RateLimit() OVERRIDE; bool buffered_updates() const { return settings_.max_partial_texture_updates != std::numeric_limits::max(); } bool RequestPartialTextureUpdate(); void SetDeviceScaleFactor(float device_scale_factor); float device_scale_factor() const { return device_scale_factor_; } void UpdateTopControlsState(TopControlsState constraints, TopControlsState current, bool animate); HeadsUpDisplayLayer* hud_layer() const { return hud_layer_.get(); } Proxy* proxy() const { return proxy_.get(); } AnimationRegistrar* animation_registrar() const { return animation_registrar_.get(); } skia::RefPtr CapturePicture(); bool BlocksPendingCommit() const; // Obtains a thorough dump of the LayerTreeHost as a value. scoped_ptr AsValue() const; bool in_paint_layer_contents() const { return in_paint_layer_contents_; } void IncrementLCDTextMetrics( bool update_total_num_cc_layers_can_use_lcd_text, bool update_total_num_cc_layers_will_use_lcd_text); protected: LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings); bool Initialize(scoped_ptr impl_thread); bool InitializeForTesting(scoped_ptr proxy_for_testing); private: bool InitializeProxy(scoped_ptr proxy); bool PaintLayerContents(const LayerList& render_surface_layer_list, ResourceUpdateQueue* quue); bool PaintMasksForRenderSurface(Layer* render_surface_layer, ResourceUpdateQueue* queue, RenderingStats* stats); void UpdateLayers(Layer* root_layer, ResourceUpdateQueue* queue); void UpdateHudLayer(); void TriggerPrepaint(); void ReduceMemoryUsage(); void PrioritizeTextures(const LayerList& render_surface_layer_list, OverdrawMetrics* metrics); void SetPrioritiesForSurfaces(size_t surface_memory_bytes); void SetPrioritiesForLayers(const LayerList& update_list); size_t CalculateMemoryForRenderSurfaces(const LayerList& update_list); bool AnimateLayersRecursive(Layer* current, base::TimeTicks time); bool animating_; bool needs_full_tree_sync_; bool needs_filter_context_; base::CancelableClosure prepaint_callback_; LayerTreeHostClient* client_; scoped_ptr proxy_; int commit_number_; scoped_ptr rendering_stats_instrumentation_; bool output_surface_can_be_initialized_; bool output_surface_lost_; int num_failed_recreate_attempts_; scoped_refptr root_layer_; scoped_refptr hud_layer_; scoped_ptr contents_texture_manager_; scoped_ptr surface_memory_placeholder_; base::WeakPtr input_handler_weak_ptr_; base::WeakPtr top_controls_manager_weak_ptr_; LayerTreeSettings settings_; LayerTreeDebugState debug_state_; gfx::Size device_viewport_size_; float overdraw_bottom_height_; float device_scale_factor_; bool visible_; typedef base::hash_map > RateLimiterMap; RateLimiterMap rate_limiters_; float page_scale_factor_; float min_page_scale_factor_; float max_page_scale_factor_; gfx::Transform impl_transform_; bool trigger_idle_updates_; SkColor background_color_; bool has_transparent_background_; typedef ScopedPtrVector TextureList; size_t partial_texture_update_requests_; scoped_ptr animation_registrar_; struct PendingPageScaleAnimation { gfx::Vector2d target_offset; bool use_anchor; float scale; base::TimeDelta duration; }; scoped_ptr pending_page_scale_animation_; bool in_paint_layer_contents_; ui::LatencyInfo latency_info_; static const int kTotalFramesToUseForLCDTextMetrics = 50; int total_frames_used_for_lcd_text_metrics_; struct LCDTextMetrics { LCDTextMetrics() : total_num_cc_layers(0), total_num_cc_layers_can_use_lcd_text(0), total_num_cc_layers_will_use_lcd_text(0) {} int64 total_num_cc_layers; int64 total_num_cc_layers_can_use_lcd_text; int64 total_num_cc_layers_will_use_lcd_text; }; LCDTextMetrics lcd_text_metrics_; DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); }; } // namespace cc #endif // CC_TREES_LAYER_TREE_HOST_H_