// Copyright 2012 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_OUTPUT_OUTPUT_SURFACE_H_ #define CC_OUTPUT_OUTPUT_SURFACE_H_ #include #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/context_provider.h" #include "cc/output/overlay_candidate_validator.h" #include "cc/output/software_output_device.h" namespace base { class SingleThreadTaskRunner; } namespace ui { struct LatencyInfo; } namespace gfx { class Rect; class Size; class Transform; } namespace cc { class CompositorFrame; class CompositorFrameAck; struct ManagedMemoryPolicy; class OutputSurfaceClient; // Represents the output surface for a compositor. The compositor owns // and manages its destruction. Its lifetime is: // 1. Created on the main thread by the LayerTreeHost through its client. // 2. Passed to the compositor thread and bound to a client via BindToClient. // From here on, it will only be used on the compositor thread. // 3. If the 3D context is lost, then the compositor will delete the output // surface (on the compositor thread) and go back to step 1. class CC_EXPORT OutputSurface { public: enum { DEFAULT_MAX_FRAMES_PENDING = 2 }; OutputSurface(const scoped_refptr& context_provider, const scoped_refptr& worker_context_provider, scoped_ptr software_device); OutputSurface(const scoped_refptr& context_provider, const scoped_refptr& worker_context_provider); explicit OutputSurface( const scoped_refptr& context_provider); explicit OutputSurface(scoped_ptr software_device); OutputSurface(const scoped_refptr& context_provider, scoped_ptr software_device); virtual ~OutputSurface(); struct Capabilities { Capabilities() : delegated_rendering(false), max_frames_pending(0), draw_and_swap_full_viewport_every_frame(false), adjust_deadline_for_parent(true), uses_default_gl_framebuffer(true), flipped_output_surface(false), can_force_reclaim_resources(false), delegated_sync_points_required(true) {} bool delegated_rendering; int max_frames_pending; bool draw_and_swap_full_viewport_every_frame; // This doesn't handle the case, but once BeginFrame is // supported natively, we shouldn't need adjust_deadline_for_parent. bool adjust_deadline_for_parent; // Whether this output surface renders to the default OpenGL zero // framebuffer or to an offscreen framebuffer. bool uses_default_gl_framebuffer; // Whether this OutputSurface is flipped or not. bool flipped_output_surface; // Whether ForceReclaimResources can be called to reclaim all resources // from the OutputSurface. bool can_force_reclaim_resources; // True if sync points for resources are needed when swapping delegated // frames. bool delegated_sync_points_required; }; const Capabilities& capabilities() const { return capabilities_; } virtual bool HasExternalStencilTest() const; // Obtain the 3d context or the software device associated with this output // surface. Either of these may return a null pointer, but not both. // In the event of a lost context, the entire output surface should be // recreated. ContextProvider* context_provider() const { return context_provider_.get(); } ContextProvider* worker_context_provider() const { return worker_context_provider_.get(); } SoftwareOutputDevice* software_device() const { return software_device_.get(); } // Called by the compositor on the compositor thread. This is a place where // thread-specific data for the output surface can be initialized, since from // this point on the output surface will only be used on the compositor // thread. virtual bool BindToClient(OutputSurfaceClient* client); virtual void EnsureBackbuffer(); virtual void DiscardBackbuffer(); virtual void Reshape(const gfx::Size& size, float scale_factor); virtual gfx::Size SurfaceSize() const; // If supported, this causes a ReclaimResources for all resources that are // currently in use. virtual void ForceReclaimResources() {} virtual void BindFramebuffer(); // The implementation may destroy or steal the contents of the CompositorFrame // passed in (though it will not take ownership of the CompositorFrame // itself). For successful swaps, the implementation must call // OutputSurfaceClient::DidSwapBuffers() and eventually // DidSwapBuffersComplete(). virtual void SwapBuffers(CompositorFrame* frame) = 0; virtual void OnSwapBuffersComplete(); // Notifies frame-rate smoothness preference. If true, all non-critical // processing should be stopped, or lowered in priority. virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {} bool HasClient() { return !!client_; } // Get the class capable of informing cc of hardware overlay capability. virtual OverlayCandidateValidator* GetOverlayCandidateValidator() const; void DidLoseOutputSurface(); void SetMemoryPolicy(const ManagedMemoryPolicy& policy); // Support for a pull-model where draws are requested by the output surface. // // OutputSurface::Invalidate is called by the compositor to notify that // there's new content. virtual void Invalidate() {} protected: OutputSurfaceClient* client_; void PostSwapBuffersComplete(); struct OutputSurface::Capabilities capabilities_; scoped_refptr context_provider_; scoped_refptr worker_context_provider_; scoped_ptr software_device_; gfx::Size surface_size_; float device_scale_factor_; void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval); void SetNeedsRedrawRect(const gfx::Rect& damage_rect); void ReclaimResources(const CompositorFrameAck* ack); void SetExternalStencilTest(bool enabled); void SetExternalDrawConstraints( const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, const gfx::Rect& viewport_rect_for_tile_priority, const gfx::Transform& transform_for_tile_priority, bool resourceless_software_draw); private: bool external_stencil_test_enabled_; base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(OutputSurface); }; } // namespace cc #endif // CC_OUTPUT_OUTPUT_SURFACE_H_