blob: b9b5b95c02631e476cf1fbd76347af5052506b42 [file] [log] [blame]
// 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.
#include <stddef.h>
#include <stdint.h>
#include <list>
#include <memory>
#include <vector>
#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 {
// Specifies what type of data is contained in the mailboxes, as well as how
// many mailboxes will be present.
enum ResourceType {
// TODO(danakj): Remove this and abstract TextureMailbox into
// "ExternalResource" that can hold a hardware or software backing.
ResourceType type;
std::vector<TextureMailbox> mailboxes;
std::vector<ReleaseCallbackImpl> release_callbacks;
bool read_lock_fences_enabled;
// TODO(danakj): Remove these too.
std::vector<unsigned> 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(const VideoFrameExternalResources& other);
// VideoResourceUpdater is used by the video system to produce frame content as
// resources consumable by the compositor.
class CC_EXPORT VideoResourceUpdater
: public base::SupportsWeakPtr<VideoResourceUpdater> {
VideoResourceUpdater(ContextProvider* context_provider,
ResourceProvider* resource_provider);
VideoFrameExternalResources CreateExternalResourcesFromVideoFrame(
scoped_refptr<media::VideoFrame> video_frame);
// Base class for converting short integers to half-floats.
// TODO(hubbe): Move this to media/.
class HalfFloatMaker {
// 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<HalfFloatMaker> NewHalfFloatMaker(
int bits_per_channel);
class PlaneResource {
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; }
// 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<PlaneResource> 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<media::VideoFrame> video_frame);
VideoFrameExternalResources CreateForSoftwarePlanes(
scoped_refptr<media::VideoFrame> video_frame);
static void RecycleResource(base::WeakPtr<VideoResourceUpdater> updater,
unsigned resource_id,
const gpu::SyncToken& sync_token,
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner);
static void ReturnTexture(base::WeakPtr<VideoResourceUpdater> updater,
const scoped_refptr<media::VideoFrame>& video_frame,
const gpu::SyncToken& sync_token,
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner);
ContextProvider* context_provider_;
ResourceProvider* resource_provider_;
std::unique_ptr<media::SkCanvasVideoRenderer> video_renderer_;
std::vector<uint8_t> upload_pixels_;
// Recycle resources so that we can reduce the number of allocations and
// data transfers.
ResourceList all_resources_;
} // namespace cc