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