Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1708)

Side by Side Diff: content/browser/renderer_host/compositing_iosurface_mac.h

Issue 490393002: Simplify IOSurface CoreAnimation code: Part 2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Lower similarity Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_
7
8 #include <deque>
9 #include <list>
10 #include <vector>
11
12 #import <Cocoa/Cocoa.h>
13 #include <IOSurface/IOSurfaceAPI.h>
14 #include <QuartzCore/QuartzCore.h>
15
16 #include "base/callback.h"
17 #include "base/lazy_instance.h"
18 #include "base/mac/scoped_cftyperef.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/time/time.h"
22 #include "base/timer/timer.h"
23 #include "media/base/video_frame.h"
24 #include "ui/gfx/native_widget_types.h"
25 #include "ui/gfx/rect.h"
26 #include "ui/gfx/rect_conversions.h"
27 #include "ui/gfx/size.h"
28
29 class SkBitmap;
30
31 namespace gfx {
32 class Rect;
33 }
34
35 namespace content {
36
37 class CompositingIOSurfaceContext;
38 class CompositingIOSurfaceShaderPrograms;
39 class CompositingIOSurfaceTransformer;
40 class RenderWidgetHostViewFrameSubscriber;
41 class RenderWidgetHostViewMac;
42
43 // This class manages an OpenGL context and IOSurface for the accelerated
44 // compositing code path. The GL context is attached to
45 // RenderWidgetHostViewCocoa for blitting the IOSurface.
46 class CompositingIOSurfaceMac
47 : public base::RefCounted<CompositingIOSurfaceMac> {
48 public:
49 // Returns NULL if IOSurface or GL API calls fail.
50 static scoped_refptr<CompositingIOSurfaceMac> Create();
51
52 // Set IOSurface that will be drawn on the next NSView drawRect.
53 bool SetIOSurfaceWithContextCurrent(
54 scoped_refptr<CompositingIOSurfaceContext> current_context,
55 IOSurfaceID io_surface_handle,
56 const gfx::Size& size,
57 float scale_factor) WARN_UNUSED_RESULT;
58
59 // Get the CGL renderer ID currently associated with this context.
60 int GetRendererID();
61
62 // Blit the IOSurface to the rectangle specified by |window_rect| in DIPs,
63 // with the origin in the lower left corner. If the window rect's size is
64 // larger than the IOSurface, the remaining right and bottom edges will be
65 // white. |window_scale_factor| is 1 in normal views, 2 in HiDPI views.
66 bool DrawIOSurface(
67 scoped_refptr<CompositingIOSurfaceContext> drawing_context,
68 const gfx::Rect& window_rect,
69 float window_scale_factor) WARN_UNUSED_RESULT;
70
71 // Copy the data of the "live" OpenGL texture referring to this IOSurfaceRef
72 // into |out|. The copied region is specified with |src_pixel_subrect| and
73 // the data is transformed so that it fits in |dst_pixel_size|.
74 // |src_pixel_subrect| and |dst_pixel_size| are not in DIP but in pixel.
75 // Caller must ensure that |out| is allocated to dimensions that match
76 // dst_pixel_size, with no additional padding.
77 // |callback| is invoked when the operation is completed or failed.
78 // Do no call this method again before |callback| is invoked.
79 void CopyTo(const gfx::Rect& src_pixel_subrect,
80 const gfx::Size& dst_pixel_size,
81 const base::Callback<void(bool, const SkBitmap&)>& callback);
82
83 // Transfer the contents of the surface to an already-allocated YV12
84 // VideoFrame, and invoke a callback to indicate success or failure.
85 void CopyToVideoFrame(
86 const gfx::Rect& src_subrect,
87 const scoped_refptr<media::VideoFrame>& target,
88 const base::Callback<void(bool)>& callback);
89
90 // Unref the IOSurface and delete the associated GL texture. If the GPU
91 // process is no longer referencing it, this will delete the IOSurface.
92 void UnrefIOSurface();
93
94 bool HasIOSurface() { return !!io_surface_.get(); }
95
96 const gfx::Size& pixel_io_surface_size() const {
97 return pixel_io_surface_size_;
98 }
99 // In cocoa view units / DIPs.
100 const gfx::Size& dip_io_surface_size() const { return dip_io_surface_size_; }
101 float scale_factor() const { return scale_factor_; }
102
103 // Returns true if asynchronous readback is supported on this system.
104 bool IsAsynchronousReadbackSupported();
105
106 // Scan the list of started asynchronous copies and test if each one has
107 // completed. If |block_until_finished| is true, then block until all
108 // pending copies are finished.
109 void CheckIfAllCopiesAreFinished(bool block_until_finished);
110
111 // Returns true if the offscreen context used by this surface has been
112 // poisoned.
113 bool HasBeenPoisoned() const;
114
115 private:
116 friend class base::RefCounted<CompositingIOSurfaceMac>;
117
118 // Vertex structure for use in glDraw calls.
119 struct SurfaceVertex {
120 SurfaceVertex() : x_(0.0f), y_(0.0f), tx_(0.0f), ty_(0.0f) { }
121 void set(float x, float y, float tx, float ty) {
122 x_ = x;
123 y_ = y;
124 tx_ = tx;
125 ty_ = ty;
126 }
127 void set_position(float x, float y) {
128 x_ = x;
129 y_ = y;
130 }
131 void set_texcoord(float tx, float ty) {
132 tx_ = tx;
133 ty_ = ty;
134 }
135 float x_;
136 float y_;
137 float tx_;
138 float ty_;
139 };
140
141 // Counter-clockwise verts starting from upper-left corner (0, 0).
142 struct SurfaceQuad {
143 void set_size(gfx::Size vertex_size, gfx::Size texcoord_size) {
144 // Texture coordinates are flipped vertically so they can be drawn on
145 // a projection with a flipped y-axis (origin is top left).
146 float vw = static_cast<float>(vertex_size.width());
147 float vh = static_cast<float>(vertex_size.height());
148 float tw = static_cast<float>(texcoord_size.width());
149 float th = static_cast<float>(texcoord_size.height());
150 verts_[0].set(0.0f, 0.0f, 0.0f, th);
151 verts_[1].set(0.0f, vh, 0.0f, 0.0f);
152 verts_[2].set(vw, vh, tw, 0.0f);
153 verts_[3].set(vw, 0.0f, tw, th);
154 }
155 void set_rect(float x1, float y1, float x2, float y2) {
156 verts_[0].set_position(x1, y1);
157 verts_[1].set_position(x1, y2);
158 verts_[2].set_position(x2, y2);
159 verts_[3].set_position(x2, y1);
160 }
161 void set_texcoord_rect(float tx1, float ty1, float tx2, float ty2) {
162 // Texture coordinates are flipped vertically so they can be drawn on
163 // a projection with a flipped y-axis (origin is top left).
164 verts_[0].set_texcoord(tx1, ty2);
165 verts_[1].set_texcoord(tx1, ty1);
166 verts_[2].set_texcoord(tx2, ty1);
167 verts_[3].set_texcoord(tx2, ty2);
168 }
169 SurfaceVertex verts_[4];
170 };
171
172 CompositingIOSurfaceMac(
173 const scoped_refptr<CompositingIOSurfaceContext>& context);
174 ~CompositingIOSurfaceMac();
175
176 // Returns true if IOSurface is ready to render. False otherwise.
177 bool MapIOSurfaceToTextureWithContextCurrent(
178 const scoped_refptr<CompositingIOSurfaceContext>& current_context,
179 const gfx::Size pixel_size,
180 float scale_factor,
181 IOSurfaceID io_surface_handle) WARN_UNUSED_RESULT;
182
183 void UnrefIOSurfaceWithContextCurrent();
184
185 void DrawQuad(const SurfaceQuad& quad);
186
187 // Check for GL errors and store the result in error_. Only return new
188 // errors
189 GLenum GetAndSaveGLError();
190
191 // Offscreen context used for all operations other than drawing to the
192 // screen. This is in the same share group as the contexts used for
193 // drawing, and is the same for all IOSurfaces in all windows.
194 scoped_refptr<CompositingIOSurfaceContext> offscreen_context_;
195
196 // IOSurface data.
197 IOSurfaceID io_surface_handle_;
198 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
199
200 // The width and height of the io surface.
201 gfx::Size pixel_io_surface_size_; // In pixels.
202 gfx::Size dip_io_surface_size_; // In view / density independent pixels.
203 float scale_factor_;
204
205 // The "live" OpenGL texture referring to this IOSurfaceRef. Note
206 // that per the CGLTexImageIOSurface2D API we do not need to
207 // explicitly update this texture's contents once created. All we
208 // need to do is ensure it is re-bound before attempting to draw
209 // with it.
210 GLuint texture_;
211
212 // Error saved by GetAndSaveGLError
213 GLint gl_error_;
214
215 // Aggressive IOSurface eviction logic. When using CoreAnimation, IOSurfaces
216 // are used only transiently to transfer from the GPU process to the browser
217 // process. Once the IOSurface has been drawn to its CALayer, the CALayer
218 // will not need updating again until its view is hidden and re-shown.
219 // Aggressively evict surfaces when more than 8 (the number allowed by the
220 // memory manager for fast tab switching) are allocated.
221 enum {
222 kMaximumUnevictedSurfaces = 8,
223 };
224 typedef std::list<CompositingIOSurfaceMac*> EvictionQueue;
225 void EvictionMarkUpdated();
226 void EvictionMarkEvicted();
227 EvictionQueue::iterator eviction_queue_iterator_;
228 bool eviction_has_been_drawn_since_updated_;
229
230 static void EvictionScheduleDoEvict();
231 static void EvictionDoEvict();
232 static base::LazyInstance<EvictionQueue> eviction_queue_;
233 static bool eviction_scheduled_;
234 };
235
236 } // namespace content
237
238 #endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698