| 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 |
| 172 CompositingIOSurfaceMac( | 205 CompositingIOSurfaceMac( |
| 173 const scoped_refptr<CompositingIOSurfaceContext>& context); | 206 const scoped_refptr<CompositingIOSurfaceContext>& context); |
| 174 ~CompositingIOSurfaceMac(); | 207 ~CompositingIOSurfaceMac(); |
| 175 | 208 |
| 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 |
| 176 // Returns true if IOSurface is ready to render. False otherwise. | 215 // Returns true if IOSurface is ready to render. False otherwise. |
| 177 bool MapIOSurfaceToTextureWithContextCurrent( | 216 bool MapIOSurfaceToTextureWithContextCurrent( |
| 178 const scoped_refptr<CompositingIOSurfaceContext>& current_context, | 217 const scoped_refptr<CompositingIOSurfaceContext>& current_context, |
| 179 const gfx::Size pixel_size, | 218 const gfx::Size pixel_size, |
| 180 float scale_factor, | 219 float scale_factor, |
| 181 IOSurfaceID io_surface_handle) WARN_UNUSED_RESULT; | 220 IOSurfaceID io_surface_handle) WARN_UNUSED_RESULT; |
| 182 | 221 |
| 183 void UnrefIOSurfaceWithContextCurrent(); | 222 void UnrefIOSurfaceWithContextCurrent(); |
| 184 | 223 |
| 185 void DrawQuad(const SurfaceQuad& quad); | 224 void DrawQuad(const SurfaceQuad& quad); |
| 186 | 225 |
| 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 |
| 187 // Check for GL errors and store the result in error_. Only return new | 268 // Check for GL errors and store the result in error_. Only return new |
| 188 // errors | 269 // errors |
| 189 GLenum GetAndSaveGLError(); | 270 GLenum GetAndSaveGLError(); |
| 190 | 271 |
| 272 gfx::Rect IntersectWithIOSurface(const gfx::Rect& rect) const; |
| 273 |
| 191 // Offscreen context used for all operations other than drawing to the | 274 // 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 | 275 // 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. | 276 // drawing, and is the same for all IOSurfaces in all windows. |
| 194 scoped_refptr<CompositingIOSurfaceContext> offscreen_context_; | 277 scoped_refptr<CompositingIOSurfaceContext> offscreen_context_; |
| 195 | 278 |
| 196 // IOSurface data. | 279 // IOSurface data. |
| 197 IOSurfaceID io_surface_handle_; | 280 IOSurfaceID io_surface_handle_; |
| 198 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; | 281 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; |
| 199 | 282 |
| 200 // The width and height of the io surface. | 283 // The width and height of the io surface. |
| 201 gfx::Size pixel_io_surface_size_; // In pixels. | 284 gfx::Size pixel_io_surface_size_; // In pixels. |
| 202 gfx::Size dip_io_surface_size_; // In view / density independent pixels. | 285 gfx::Size dip_io_surface_size_; // In view / density independent pixels. |
| 203 float scale_factor_; | 286 float scale_factor_; |
| 204 | 287 |
| 205 // The "live" OpenGL texture referring to this IOSurfaceRef. Note | 288 // The "live" OpenGL texture referring to this IOSurfaceRef. Note |
| 206 // that per the CGLTexImageIOSurface2D API we do not need to | 289 // that per the CGLTexImageIOSurface2D API we do not need to |
| 207 // explicitly update this texture's contents once created. All we | 290 // explicitly update this texture's contents once created. All we |
| 208 // need to do is ensure it is re-bound before attempting to draw | 291 // need to do is ensure it is re-bound before attempting to draw |
| 209 // with it. | 292 // with it. |
| 210 GLuint texture_; | 293 GLuint texture_; |
| 211 | 294 |
| 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 |
| 212 // Error saved by GetAndSaveGLError | 305 // Error saved by GetAndSaveGLError |
| 213 GLint gl_error_; | 306 GLint gl_error_; |
| 214 | 307 |
| 215 // Aggressive IOSurface eviction logic. When using CoreAnimation, IOSurfaces | 308 // Aggressive IOSurface eviction logic. When using CoreAnimation, IOSurfaces |
| 216 // are used only transiently to transfer from the GPU process to the browser | 309 // 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 | 310 // 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. | 311 // 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 | 312 // Aggressively evict surfaces when more than 8 (the number allowed by the |
| 220 // memory manager for fast tab switching) are allocated. | 313 // memory manager for fast tab switching) are allocated. |
| 221 enum { | 314 enum { |
| 222 kMaximumUnevictedSurfaces = 8, | 315 kMaximumUnevictedSurfaces = 8, |
| 223 }; | 316 }; |
| 224 typedef std::list<CompositingIOSurfaceMac*> EvictionQueue; | 317 typedef std::list<CompositingIOSurfaceMac*> EvictionQueue; |
| 225 void EvictionMarkUpdated(); | 318 void EvictionMarkUpdated(); |
| 226 void EvictionMarkEvicted(); | 319 void EvictionMarkEvicted(); |
| 227 EvictionQueue::iterator eviction_queue_iterator_; | 320 EvictionQueue::iterator eviction_queue_iterator_; |
| 228 bool eviction_has_been_drawn_since_updated_; | 321 bool eviction_has_been_drawn_since_updated_; |
| 229 | 322 |
| 230 static void EvictionScheduleDoEvict(); | 323 static void EvictionScheduleDoEvict(); |
| 231 static void EvictionDoEvict(); | 324 static void EvictionDoEvict(); |
| 232 static base::LazyInstance<EvictionQueue> eviction_queue_; | 325 static base::LazyInstance<EvictionQueue> eviction_queue_; |
| 233 static bool eviction_scheduled_; | 326 static bool eviction_scheduled_; |
| 234 }; | 327 }; |
| 235 | 328 |
| 236 } // namespace content | 329 } // namespace content |
| 237 | 330 |
| 238 #endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ | 331 #endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_ |
| OLD | NEW |