// Copyright 2013 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_RESOURCES_VIDEO_RESOURCE_UPDATER_H_ #define CC_RESOURCES_VIDEO_RESOURCE_UPDATER_H_ #include #include #include #include #include #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/resources/release_callback_impl.h" #include "cc/resources/resource_format.h" #include "cc/resources/texture_mailbox.h" #include "ui/gfx/geometry/size.h" namespace media { class SkCanvasVideoRenderer; class VideoFrame; } namespace cc { class ContextProvider; class ResourceProvider; class CC_EXPORT VideoFrameExternalResources { public: // Specifies what type of data is contained in the mailboxes, as well as how // many mailboxes will be present. enum ResourceType { NONE, YUV_RESOURCE, RGB_RESOURCE, RGBA_PREMULTIPLIED_RESOURCE, RGBA_RESOURCE, STREAM_TEXTURE_RESOURCE, // TODO(danakj): Remove this and abstract TextureMailbox into // "ExternalResource" that can hold a hardware or software backing. SOFTWARE_RESOURCE }; ResourceType type; std::vector mailboxes; std::vector release_callbacks; bool read_lock_fences_enabled; // TODO(danakj): Remove these too. std::vector software_resources; ReleaseCallbackImpl software_release_callback; // Used by hardware textures which do not return values in the 0-1 range. // After a lookup, subtract offset and multiply by multiplier. float offset; float multiplier; uint32_t bits_per_channel; VideoFrameExternalResources(); VideoFrameExternalResources(const VideoFrameExternalResources& other); ~VideoFrameExternalResources(); }; // VideoResourceUpdater is used by the video system to produce frame content as // resources consumable by the compositor. class CC_EXPORT VideoResourceUpdater : public base::SupportsWeakPtr { public: VideoResourceUpdater(ContextProvider* context_provider, ResourceProvider* resource_provider); ~VideoResourceUpdater(); VideoFrameExternalResources CreateExternalResourcesFromVideoFrame( scoped_refptr video_frame); // Base class for converting short integers to half-floats. // TODO(hubbe): Move this to media/. class HalfFloatMaker { public: // Convert an array of short integers into an array of half-floats. // |src| is an array of integers in range 0 .. 2^{bits_per_channel} - 1 // |num| is number of entries in input and output array. // The numbers stored in |dst| will be half floats in range 0.0..1.0 virtual void MakeHalfFloats(const uint16_t* src, size_t num, uint16_t* dst) = 0; // The half-floats made needs by this class will be in the range // [Offset() .. Offset() + 1.0/Multiplier]. So if you want results // in the 0-1 range, you need to do: // (half_float - Offset()) * Multiplier() // to each returned value. virtual float Offset() const = 0; virtual float Multiplier() const = 0; }; static std::unique_ptr NewHalfFloatMaker( int bits_per_channel); private: class PlaneResource { public: PlaneResource(unsigned resource_id, const gfx::Size& resource_size, ResourceFormat resource_format, gpu::Mailbox mailbox); PlaneResource(const PlaneResource& other); // Returns true if this resource matches the unique identifiers of another // VideoFrame resource. bool Matches(int unique_frame_id, size_t plane_index); // Sets the unique identifiers for this resource, may only be called when // there is a single reference to the resource (i.e. |ref_count_| == 1). void SetUniqueId(int unique_frame_id, size_t plane_index); // Accessors for resource identifiers provided at construction time. unsigned resource_id() const { return resource_id_; } const gfx::Size& resource_size() const { return resource_size_; } ResourceFormat resource_format() const { return resource_format_; } const gpu::Mailbox& mailbox() const { return mailbox_; } // Various methods for managing references. See |ref_count_| for details. void add_ref() { ++ref_count_; } void remove_ref() { --ref_count_; } void clear_refs() { ref_count_ = 0; } bool has_refs() const { return ref_count_ != 0; } private: // The balance between the number of times this resource has been returned // from CreateForSoftwarePlanes vs released in RecycleResource. int ref_count_ = 0; // These two members are used for identifying the data stored in this // resource; they uniquely identify a media::VideoFrame plane. int unique_frame_id_ = 0; size_t plane_index_ = 0u; // Indicates if the above two members have been set or not. bool has_unique_frame_id_and_plane_index_ = false; const unsigned resource_id_; const gfx::Size resource_size_; const ResourceFormat resource_format_; const gpu::Mailbox mailbox_; }; // This needs to be a container where iterators can be erased without // invalidating other iterators. typedef std::list ResourceList; // Obtain a resource of the right format by either recycling an // unreferenced but appropriately formatted resource, or by // allocating a new resource. // Additionally, if the |unique_id| and |plane_index| match, then // it is assumed that the resource has the right data already and will only be // used for reading, and so is returned even if it is still referenced. // Passing -1 for |plane_index| avoids returning referenced // resources. ResourceList::iterator RecycleOrAllocateResource( const gfx::Size& resource_size, ResourceFormat resource_format, const gfx::ColorSpace& color_space, bool software_resource, bool immutable_hint, int unique_id, int plane_index); ResourceList::iterator AllocateResource(const gfx::Size& plane_size, ResourceFormat format, const gfx::ColorSpace& color_space, bool has_mailbox, bool immutable_hint); void DeleteResource(ResourceList::iterator resource_it); void CopyPlaneTexture(media::VideoFrame* video_frame, const gpu::MailboxHolder& mailbox_holder, VideoFrameExternalResources* external_resources); VideoFrameExternalResources CreateForHardwarePlanes( scoped_refptr video_frame); VideoFrameExternalResources CreateForSoftwarePlanes( scoped_refptr video_frame); static void RecycleResource(base::WeakPtr updater, unsigned resource_id, const gpu::SyncToken& sync_token, bool lost_resource, BlockingTaskRunner* main_thread_task_runner); static void ReturnTexture(base::WeakPtr updater, const scoped_refptr& video_frame, const gpu::SyncToken& sync_token, bool lost_resource, BlockingTaskRunner* main_thread_task_runner); ContextProvider* context_provider_; ResourceProvider* resource_provider_; std::unique_ptr video_renderer_; std::vector upload_pixels_; // Recycle resources so that we can reduce the number of allocations and // data transfers. ResourceList all_resources_; DISALLOW_COPY_AND_ASSIGN(VideoResourceUpdater); }; } // namespace cc #endif // CC_RESOURCES_VIDEO_RESOURCE_UPDATER_H_