OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ | 5 #ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ |
6 #define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ | 6 #define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <list> | 9 #include <list> |
10 #include <vector> | 10 #include <vector> |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 // Texture coordinates are flipped vertically so they can be drawn on | 162 // Texture coordinates are flipped vertically so they can be drawn on |
163 // a projection with a flipped y-axis (origin is top left). | 163 // a projection with a flipped y-axis (origin is top left). |
164 verts_[0].set_texcoord(tx1, ty2); | 164 verts_[0].set_texcoord(tx1, ty2); |
165 verts_[1].set_texcoord(tx1, ty1); | 165 verts_[1].set_texcoord(tx1, ty1); |
166 verts_[2].set_texcoord(tx2, ty1); | 166 verts_[2].set_texcoord(tx2, ty1); |
167 verts_[3].set_texcoord(tx2, ty2); | 167 verts_[3].set_texcoord(tx2, ty2); |
168 } | 168 } |
169 SurfaceVertex verts_[4]; | 169 SurfaceVertex verts_[4]; |
170 }; | 170 }; |
171 | 171 |
172 // Keeps track of states and buffers for readback of IOSurface. | |
173 // | |
174 // TODO(miu): Major code refactoring is badly needed! To be done in a | |
175 // soon-upcoming change. For now, we blatantly violate the style guide with | |
176 // respect to struct vs. class usage: | |
177 struct CopyContext { | |
178 explicit CopyContext(const scoped_refptr<CompositingIOSurfaceContext>& ctx); | |
179 ~CopyContext(); | |
180 | |
181 // Delete any references to owned OpenGL objects. This must be called | |
182 // within the OpenGL context just before destruction. | |
183 void ReleaseCachedGLObjects(); | |
184 | |
185 // The following two methods assume |num_outputs| has been set, and are | |
186 // being called within the OpenGL context. | |
187 void PrepareReadbackFramebuffers(); | |
188 void PrepareForAsynchronousReadback(); | |
189 | |
190 const scoped_ptr<CompositingIOSurfaceTransformer> transformer; | |
191 GLenum output_readback_format; | |
192 int num_outputs; | |
193 GLuint output_textures[3]; // Not owned. | |
194 // Note: For YUV, the |output_texture_sizes| widths are in terms of 4-byte | |
195 // quads, not pixels. | |
196 gfx::Size output_texture_sizes[3]; | |
197 GLuint frame_buffers[3]; | |
198 GLuint pixel_buffers[3]; | |
199 GLuint fence; // When non-zero, doing an asynchronous copy. | |
200 int cycles_elapsed; | |
201 base::Callback<bool(const void*, int)> map_buffer_callback; | |
202 base::Callback<void(bool)> done_callback; | |
203 }; | |
204 | |
205 CompositingIOSurfaceMac( | 172 CompositingIOSurfaceMac( |
206 const scoped_refptr<CompositingIOSurfaceContext>& context); | 173 const scoped_refptr<CompositingIOSurfaceContext>& context); |
207 ~CompositingIOSurfaceMac(); | 174 ~CompositingIOSurfaceMac(); |
208 | 175 |
209 // If this IOSurface has moved to a different window, use that window's | |
210 // GL context (if multiple visible windows are using the same GL context | |
211 // then call to setView call can stall and prevent reaching 60fps). | |
212 void SwitchToContextOnNewWindow(NSView* view, | |
213 int window_number); | |
214 | |
215 // Returns true if IOSurface is ready to render. False otherwise. | 176 // Returns true if IOSurface is ready to render. False otherwise. |
216 bool MapIOSurfaceToTextureWithContextCurrent( | 177 bool MapIOSurfaceToTextureWithContextCurrent( |
217 const scoped_refptr<CompositingIOSurfaceContext>& current_context, | 178 const scoped_refptr<CompositingIOSurfaceContext>& current_context, |
218 const gfx::Size pixel_size, | 179 const gfx::Size pixel_size, |
219 float scale_factor, | 180 float scale_factor, |
220 IOSurfaceID io_surface_handle) WARN_UNUSED_RESULT; | 181 IOSurfaceID io_surface_handle) WARN_UNUSED_RESULT; |
221 | 182 |
222 void UnrefIOSurfaceWithContextCurrent(); | 183 void UnrefIOSurfaceWithContextCurrent(); |
223 | 184 |
224 void DrawQuad(const SurfaceQuad& quad); | 185 void DrawQuad(const SurfaceQuad& quad); |
225 | 186 |
226 // Copy current frame to |target| video frame. This method must be called | |
227 // within a CGL context. Returns a callback that should be called outside | |
228 // of the CGL context. | |
229 // If |called_within_draw| is true this method is called within a drawing | |
230 // operations. This allow certain optimizations. | |
231 base::Closure CopyToVideoFrameWithinContext( | |
232 const gfx::Rect& src_subrect, | |
233 bool called_within_draw, | |
234 const scoped_refptr<media::VideoFrame>& target, | |
235 const base::Callback<void(bool)>& callback); | |
236 | |
237 // Common GPU-readback copy path. Only one of |bitmap_output| or | |
238 // |video_frame_output| may be specified: Either ARGB is written to | |
239 // |bitmap_output| or letter-boxed YV12 is written to |video_frame_output|. | |
240 base::Closure CopyToSelectedOutputWithinContext( | |
241 const gfx::Rect& src_pixel_subrect, | |
242 const gfx::Rect& dst_pixel_rect, | |
243 bool called_within_draw, | |
244 const SkBitmap* bitmap_output, | |
245 const scoped_refptr<media::VideoFrame>& video_frame_output, | |
246 const base::Callback<void(bool)>& done_callback); | |
247 | |
248 // TODO(hclam): These two methods should be static. | |
249 void AsynchronousReadbackForCopy( | |
250 const gfx::Rect& dst_pixel_rect, | |
251 bool called_within_draw, | |
252 CopyContext* copy_context, | |
253 const SkBitmap* bitmap_output, | |
254 const scoped_refptr<media::VideoFrame>& video_frame_output); | |
255 bool SynchronousReadbackForCopy( | |
256 const gfx::Rect& dst_pixel_rect, | |
257 CopyContext* copy_context, | |
258 const SkBitmap* bitmap_output, | |
259 const scoped_refptr<media::VideoFrame>& video_frame_output); | |
260 | |
261 void CheckIfAllCopiesAreFinishedWithinContext( | |
262 bool block_until_finished, | |
263 std::vector<base::Closure>* done_callbacks); | |
264 | |
265 void FailAllCopies(); | |
266 void DestroyAllCopyContextsWithinContext(); | |
267 | |
268 // Check for GL errors and store the result in error_. Only return new | 187 // Check for GL errors and store the result in error_. Only return new |
269 // errors | 188 // errors |
270 GLenum GetAndSaveGLError(); | 189 GLenum GetAndSaveGLError(); |
271 | 190 |
272 gfx::Rect IntersectWithIOSurface(const gfx::Rect& rect) const; | |
273 | |
274 // Offscreen context used for all operations other than drawing to the | 191 // Offscreen context used for all operations other than drawing to the |
275 // screen. This is in the same share group as the contexts used for | 192 // screen. This is in the same share group as the contexts used for |
276 // drawing, and is the same for all IOSurfaces in all windows. | 193 // drawing, and is the same for all IOSurfaces in all windows. |
277 scoped_refptr<CompositingIOSurfaceContext> offscreen_context_; | 194 scoped_refptr<CompositingIOSurfaceContext> offscreen_context_; |
278 | 195 |
279 // IOSurface data. | 196 // IOSurface data. |
280 IOSurfaceID io_surface_handle_; | 197 IOSurfaceID io_surface_handle_; |
281 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; | 198 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; |
282 | 199 |
283 // The width and height of the io surface. | 200 // The width and height of the io surface. |
284 gfx::Size pixel_io_surface_size_; // In pixels. | 201 gfx::Size pixel_io_surface_size_; // In pixels. |
285 gfx::Size dip_io_surface_size_; // In view / density independent pixels. | 202 gfx::Size dip_io_surface_size_; // In view / density independent pixels. |
286 float scale_factor_; | 203 float scale_factor_; |
287 | 204 |
288 // The "live" OpenGL texture referring to this IOSurfaceRef. Note | 205 // The "live" OpenGL texture referring to this IOSurfaceRef. Note |
289 // that per the CGLTexImageIOSurface2D API we do not need to | 206 // that per the CGLTexImageIOSurface2D API we do not need to |
290 // explicitly update this texture's contents once created. All we | 207 // explicitly update this texture's contents once created. All we |
291 // need to do is ensure it is re-bound before attempting to draw | 208 // need to do is ensure it is re-bound before attempting to draw |
292 // with it. | 209 // with it. |
293 GLuint texture_; | 210 GLuint texture_; |
294 | 211 |
295 // A pool of CopyContexts with OpenGL objects ready for re-use. Prefer to | |
296 // pull one from the pool before creating a new CopyContext. | |
297 std::vector<CopyContext*> copy_context_pool_; | |
298 | |
299 // CopyContexts being used for in-flight copy operations. | |
300 std::deque<CopyContext*> copy_requests_; | |
301 | |
302 // Timer for finishing a copy operation. | |
303 base::Timer finish_copy_timer_; | |
304 | |
305 // Error saved by GetAndSaveGLError | 212 // Error saved by GetAndSaveGLError |
306 GLint gl_error_; | 213 GLint gl_error_; |
307 | 214 |
308 // Aggressive IOSurface eviction logic. When using CoreAnimation, IOSurfaces | 215 // Aggressive IOSurface eviction logic. When using CoreAnimation, IOSurfaces |
309 // are used only transiently to transfer from the GPU process to the browser | 216 // are used only transiently to transfer from the GPU process to the browser |
310 // process. Once the IOSurface has been drawn to its CALayer, the CALayer | 217 // process. Once the IOSurface has been drawn to its CALayer, the CALayer |
311 // will not need updating again until its view is hidden and re-shown. | 218 // will not need updating again until its view is hidden and re-shown. |
312 // Aggressively evict surfaces when more than 8 (the number allowed by the | 219 // Aggressively evict surfaces when more than 8 (the number allowed by the |
313 // memory manager for fast tab switching) are allocated. | 220 // memory manager for fast tab switching) are allocated. |
314 enum { | 221 enum { |
315 kMaximumUnevictedSurfaces = 8, | 222 kMaximumUnevictedSurfaces = 8, |
316 }; | 223 }; |
317 typedef std::list<CompositingIOSurfaceMac*> EvictionQueue; | 224 typedef std::list<CompositingIOSurfaceMac*> EvictionQueue; |
318 void EvictionMarkUpdated(); | 225 void EvictionMarkUpdated(); |
319 void EvictionMarkEvicted(); | 226 void EvictionMarkEvicted(); |
320 EvictionQueue::iterator eviction_queue_iterator_; | 227 EvictionQueue::iterator eviction_queue_iterator_; |
321 bool eviction_has_been_drawn_since_updated_; | 228 bool eviction_has_been_drawn_since_updated_; |
322 | 229 |
323 static void EvictionScheduleDoEvict(); | 230 static void EvictionScheduleDoEvict(); |
324 static void EvictionDoEvict(); | 231 static void EvictionDoEvict(); |
325 static base::LazyInstance<EvictionQueue> eviction_queue_; | 232 static base::LazyInstance<EvictionQueue> eviction_queue_; |
326 static bool eviction_scheduled_; | 233 static bool eviction_scheduled_; |
327 }; | 234 }; |
328 | 235 |
329 } // namespace content | 236 } // namespace content |
330 | 237 |
331 #endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ | 238 #endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ |
OLD | NEW |