1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_VIZ_COMMON_FRAME_SINKS_COPY_OUTPUT_RESULT_H_
6 #define COMPONENTS_VIZ_COMMON_FRAME_SINKS_COPY_OUTPUT_RESULT_H_
7 
8 #include <memory>
9 
10 #include "components/viz/common/resources/single_release_callback.h"
11 #include "components/viz/common/viz_common_export.h"
12 #include "gpu/command_buffer/common/mailbox.h"
13 #include "gpu/command_buffer/common/sync_token.h"
14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "ui/gfx/color_space.h"
16 #include "ui/gfx/geometry/rect.h"
17 
18 class SkBitmap;
19 
20 namespace viz {
21 
22 // Base class for providing the result of a CopyOutputRequest. Implementations
23 // that execute CopyOutputRequests will use a subclass implementation to define
24 // data storage, access and ownership semantics relative to the lifetime of the
25 // CopyOutputResult instance.
26 class VIZ_COMMON_EXPORT CopyOutputResult {
27  public:
28   enum class Format : uint8_t {
29     // A normal bitmap in system memory. AsSkBitmap() will return a bitmap in
30     // "N32Premul" form.
31     RGBA_BITMAP,
32     // A GL_RGBA texture, referred to by a gpu::Mailbox. Client code can
33     // optionally take ownership of the texture (via TakeTextureOwnership()), if
34     // it is needed beyond the lifetime of CopyOutputResult.
35     RGBA_TEXTURE,
36     // I420 format planes in system memory. This is intended to be used
37     // internally within the VIZ component to support video capture. When
38     // requesting this format, results can only be delivered on the same task
39     // runner sequence that runs the DirectRenderer implementation.
40     I420_PLANES,
41   };
42 
43   CopyOutputResult(Format format, const gfx::Rect& rect);
44 
45   virtual ~CopyOutputResult();
46 
47   // Returns false if the request succeeded and the data accessors will return
48   // valid references.
49   bool IsEmpty() const;
50 
51   // Returns the format of this result.
format()52   Format format() const { return format_; }
53 
54   // Returns the result Rect, which is the position and size of the image data
55   // within the surface/layer (see CopyOutputRequest::set_area()). If a scale
56   // ratio was set in the request, this will be in the scaled, NOT the original,
57   // coordinate space.
rect()58   const gfx::Rect& rect() const { return rect_; }
size()59   const gfx::Size& size() const { return rect_.size(); }
60 
61   // Convenience to provide this result in SkBitmap form. Returns a
62   // !readyToDraw() bitmap if this result is empty or if a conversion is not
63   // possible in the current implementation. The returned SkBitmap also carries
64   // its color space information.
65   virtual const SkBitmap& AsSkBitmap() const;
66 
67   // Returns a pointer with the gpu::Mailbox referencing a RGBA_TEXTURE result,
68   // or null if this is not a RGBA_TEXTURE result. Clients can either:
69   //   1. Let CopyOutputResult retain ownership and the texture will only be
70   //      valid for use during CopyOutputResult's lifetime.
71   //   2. Take over ownership of the texture by calling TakeTextureOwnership(),
72   //      and the client must guarantee the release callback will be run at some
73   //      point.
74   // Even when non-null the resulting mailbox can be empty in the case of a
75   // failed reply, in which case IsEmpty() would report true. The texture object
76   // associated with the mailbox has a GL_TEXTURE_2D target.
77   struct TextureResult {
78     gpu::Mailbox mailbox;
79     gpu::SyncToken sync_token;
80     gfx::ColorSpace color_space;
81 
TextureResultTextureResult82     TextureResult(const gpu::Mailbox& mailbox,
83                   const gpu::SyncToken& sync_token,
84                   const gfx::ColorSpace& color_space)
85         : mailbox(mailbox), sync_token(sync_token), color_space(color_space) {}
86   };
87   virtual const TextureResult* GetTextureResult() const;
88   virtual std::unique_ptr<SingleReleaseCallback> TakeTextureOwnership();
89 
90   // Copies the image planes of an I420_PLANES result to the caller-provided
91   // memory. Returns true if successful, or false if: 1) this result is empty,
92   // or 2) the result format is not I420_PLANES and does not provide a
93   // conversion implementation.
94   //
95   // |y_out|, |u_out| and |v_out| point to the start of the memory regions to
96   // receive each plane. These memory regions must have the following sizes:
97   //
98   //   Y plane: y_out_stride * size().height() bytes, with
99   //            y_out_stride >= size().width()
100   //   U plane: u_out_stride * CEIL(size().height() / 2) bytes, with
101   //            u_out_stride >= CEIL(size().width() / 2)
102   //   V plane: v_out_stride * CEIL(size().height() / 2) bytes, with
103   //            v_out_stride >= CEIL(size().width() / 2)
104   //
105   // The color space is always Rec.709 (see gfx::ColorSpace::CreateREC709()).
106   virtual bool ReadI420Planes(uint8_t* y_out,
107                               int y_out_stride,
108                               uint8_t* u_out,
109                               int u_out_stride,
110                               uint8_t* v_out,
111                               int v_out_stride) const;
112 
113   // Copies the result of an RGBA_BITMAP into |dest|. The result is in N32Premul
114   // form. Returns true if successful, or false if: 1) the result is empty, or
115   // 2) the result format is not RGBA_BITMAP and conversion is not implemented.
116   virtual bool ReadRGBAPlane(uint8_t* dest, int stride) const;
117 
118   // Returns the color space of the image data returned by ReadRGBAPlane().
119   virtual gfx::ColorSpace GetRGBAColorSpace() const;
120 
121  protected:
122   // Accessor for subclasses to initialize the cached SkBitmap.
cached_bitmap()123   SkBitmap* cached_bitmap() const { return &cached_bitmap_; }
124 
125  private:
126   const Format format_;
127   const gfx::Rect rect_;
128 
129   // Cached bitmap returned by the default implementation of AsSkBitmap().
130   mutable SkBitmap cached_bitmap_;
131 
132   DISALLOW_COPY_AND_ASSIGN(CopyOutputResult);
133 };
134 
135 // Subclass of CopyOutputResult that provides a RGBA_BITMAP result from an
136 // SkBitmap (or an I420_PLANES result based on a SkBitmap).
137 class VIZ_COMMON_EXPORT CopyOutputSkBitmapResult : public CopyOutputResult {
138  public:
139   CopyOutputSkBitmapResult(Format format,
140                            const gfx::Rect& rect,
141                            const SkBitmap& bitmap);
142   CopyOutputSkBitmapResult(const gfx::Rect& rect, const SkBitmap& bitmap);
143   ~CopyOutputSkBitmapResult() override;
144 
145   const SkBitmap& AsSkBitmap() const override;
146 
147  private:
148   DISALLOW_COPY_AND_ASSIGN(CopyOutputSkBitmapResult);
149 };
150 
151 // Subclass of CopyOutputResult that holds a reference to a texture (via
152 // a mailbox). The owner of the result must take ownership of the texture
153 // if it wants to use it by calling TakeTextureOwnership(), and then call the
154 // SingleReleaseCallback when the texture will no longer be used to release
155 // ownership and allow the texture to be reused or destroyed. If ownership is
156 // not claimed, it will be released when this class is destroyed.
157 class VIZ_COMMON_EXPORT CopyOutputTextureResult : public CopyOutputResult {
158  public:
159   CopyOutputTextureResult(
160       const gfx::Rect& rect,
161       const gpu::Mailbox& mailbox,
162       const gpu::SyncToken& sync_token,
163       const gfx::ColorSpace& color_space,
164       std::unique_ptr<SingleReleaseCallback> release_callback);
165   ~CopyOutputTextureResult() override;
166 
167   const TextureResult* GetTextureResult() const override;
168   std::unique_ptr<SingleReleaseCallback> TakeTextureOwnership() override;
169 
170  private:
171   TextureResult texture_result_;
172   std::unique_ptr<SingleReleaseCallback> release_callback_;
173 
174   DISALLOW_COPY_AND_ASSIGN(CopyOutputTextureResult);
175 };
176 
177 }  // namespace viz
178 
179 #endif  // COMPONENTS_VIZ_COMMON_FRAME_SINKS_COPY_OUTPUT_RESULT_H_
180