Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / compositing_iosurface_mac.h
index 623272b..21e33ce 100644 (file)
@@ -6,26 +6,26 @@
 #define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_
 
 #include <deque>
+#include <list>
 #include <vector>
 
 #import <Cocoa/Cocoa.h>
-#import <QuartzCore/CVDisplayLink.h>
+#include <IOSurface/IOSurfaceAPI.h>
 #include <QuartzCore/QuartzCore.h>
 
 #include "base/callback.h"
+#include "base/lazy_instance.h"
 #include "base/mac/scoped_cftyperef.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "media/base/video_frame.h"
-#include "ui/events/latency_info.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/rect.h"
 #include "ui/gfx/rect_conversions.h"
 #include "ui/gfx/size.h"
 
-class IOSurfaceSupport;
 class SkBitmap;
 
 namespace gfx {
@@ -35,41 +35,36 @@ class Rect;
 namespace content {
 
 class CompositingIOSurfaceContext;
-class CompositingIOSurfaceShaderPrograms;
-class CompositingIOSurfaceTransformer;
 class RenderWidgetHostViewFrameSubscriber;
 class RenderWidgetHostViewMac;
 
 // This class manages an OpenGL context and IOSurface for the accelerated
 // compositing code path. The GL context is attached to
 // RenderWidgetHostViewCocoa for blitting the IOSurface.
-class CompositingIOSurfaceMac {
+class CompositingIOSurfaceMac
+    : public base::RefCounted<CompositingIOSurfaceMac> {
  public:
-  // Returns NULL if IOSurface support is missing or GL APIs fail. Specify in
-  // |order| the desired ordering relationship of the surface to the containing
-  // window.
-  static CompositingIOSurfaceMac* Create(
-      const scoped_refptr<CompositingIOSurfaceContext>& context);
-  ~CompositingIOSurfaceMac();
+  // Returns NULL if IOSurface or GL API calls fail.
+  static scoped_refptr<CompositingIOSurfaceMac> Create();
 
   // Set IOSurface that will be drawn on the next NSView drawRect.
-  bool SetIOSurface(uint64 io_surface_handle,
-                    const gfx::Size& size,
-                    float scale_factor,
-                    const ui::LatencyInfo& latency_info);
+  bool SetIOSurfaceWithContextCurrent(
+      scoped_refptr<CompositingIOSurfaceContext> current_context,
+      IOSurfaceID io_surface_handle,
+      const gfx::Size& size,
+      float scale_factor) WARN_UNUSED_RESULT;
 
   // Get the CGL renderer ID currently associated with this context.
   int GetRendererID();
 
-  // Blit the IOSurface at the upper-left corner of the of the specified
-  // window_size. If the window size is larger than the IOSurface, the
-  // remaining right and bottom edges will be white. |scaleFactor| is 1
-  // in normal views, 2 in HiDPI views.  |frame_subscriber| listens to
-  // this draw event and provides output buffer for copying this frame into.
-  bool DrawIOSurface(const gfx::Size& window_size,
-                     float window_scale_factor,
-                     RenderWidgetHostViewFrameSubscriber* frame_subscriber,
-                     bool using_core_animation);
+  // Blit the IOSurface to the rectangle specified by |window_rect| in DIPs,
+  // with the origin in the lower left corner. If the window rect's size is
+  // larger than the IOSurface, the remaining right and bottom edges will be
+  // white. |window_scale_factor| is 1 in normal views, 2 in HiDPI views.
+  bool DrawIOSurface(
+      scoped_refptr<CompositingIOSurfaceContext> drawing_context,
+      const gfx::Rect& window_rect,
+      float window_scale_factor) WARN_UNUSED_RESULT;
 
   // Copy the data of the "live" OpenGL texture referring to this IOSurfaceRef
   // into |out|. The copied region is specified with |src_pixel_subrect| and
@@ -103,32 +98,20 @@ class CompositingIOSurfaceMac {
   const gfx::Size& dip_io_surface_size() const { return dip_io_surface_size_; }
   float scale_factor() const { return scale_factor_; }
 
-  bool is_vsync_disabled() const;
-
-  void SetContext(
-      const scoped_refptr<CompositingIOSurfaceContext>& new_context);
-
-  const scoped_refptr<CompositingIOSurfaceContext>& context() {
-    return context_;
-  }
-
-  // Get vsync scheduling parameters.
-  // |interval_numerator/interval_denominator| equates to fractional number of
-  // seconds between vsyncs.
-  void GetVSyncParameters(base::TimeTicks* timebase,
-                          uint32* interval_numerator,
-                          uint32* interval_denominator);
-
   // Returns true if asynchronous readback is supported on this system.
   bool IsAsynchronousReadbackSupported();
 
+  // Scan the list of started asynchronous copies and test if each one has
+  // completed. If |block_until_finished| is true, then block until all
+  // pending copies are finished.
+  void CheckIfAllCopiesAreFinished(bool block_until_finished);
+
+  // Returns true if the offscreen context used by this surface has been
+  // poisoned.
+  bool HasBeenPoisoned() const;
+
  private:
-  friend CVReturn DisplayLinkCallback(CVDisplayLinkRef,
-                                      const CVTimeStamp*,
-                                      const CVTimeStamp*,
-                                      CVOptionFlags,
-                                      CVOptionFlags*,
-                                      void*);
+  friend class base::RefCounted<CompositingIOSurfaceMac>;
 
   // Vertex structure for use in glDraw calls.
   struct SurfaceVertex {
@@ -184,135 +167,33 @@ class CompositingIOSurfaceMac {
     SurfaceVertex verts_[4];
   };
 
-  // Keeps track of states and buffers for readback of IOSurface.
-  //
-  // TODO(miu): Major code refactoring is badly needed!  To be done in a
-  // soon-upcoming change.  For now, we blatantly violate the style guide with
-  // respect to struct vs. class usage:
-  struct CopyContext {
-    explicit CopyContext(const scoped_refptr<CompositingIOSurfaceContext>& ctx);
-    ~CopyContext();
-
-    // Delete any references to owned OpenGL objects.  This must be called
-    // within the OpenGL context just before destruction.
-    void ReleaseCachedGLObjects();
-
-    // The following two methods assume |num_outputs| has been set, and are
-    // being called within the OpenGL context.
-    void PrepareReadbackFramebuffers();
-    void PrepareForAsynchronousReadback();
-
-    const scoped_ptr<CompositingIOSurfaceTransformer> transformer;
-    GLenum output_readback_format;
-    int num_outputs;
-    GLuint output_textures[3];  // Not owned.
-    // Note: For YUV, the |output_texture_sizes| widths are in terms of 4-byte
-    // quads, not pixels.
-    gfx::Size output_texture_sizes[3];
-    GLuint frame_buffers[3];
-    GLuint pixel_buffers[3];
-    GLuint fence;  // When non-zero, doing an asynchronous copy.
-    int cycles_elapsed;
-    base::Callback<bool(const void*, int)> map_buffer_callback;
-    base::Callback<void(bool)> done_callback;
-  };
-
   CompositingIOSurfaceMac(
-      IOSurfaceSupport* io_surface_support,
       const scoped_refptr<CompositingIOSurfaceContext>& context);
-
-  void SetupCVDisplayLink();
-
-  // If this IOSurface has moved to a different window, use that window's
-  // GL context (if multiple visible windows are using the same GL context
-  // then call to setView call can stall and prevent reaching 60fps).
-  void SwitchToContextOnNewWindow(NSView* view,
-                                  int window_number);
-
-  bool IsVendorIntel();
+  ~CompositingIOSurfaceMac();
 
   // Returns true if IOSurface is ready to render. False otherwise.
-  bool MapIOSurfaceToTexture(uint64 io_surface_handle);
+  bool MapIOSurfaceToTextureWithContextCurrent(
+      const scoped_refptr<CompositingIOSurfaceContext>& current_context,
+      const gfx::Size pixel_size,
+      float scale_factor,
+      IOSurfaceID io_surface_handle) WARN_UNUSED_RESULT;
 
   void UnrefIOSurfaceWithContextCurrent();
 
   void DrawQuad(const SurfaceQuad& quad);
 
-  // Called on display-link thread.
-  void DisplayLinkTick(CVDisplayLinkRef display_link,
-                       const CVTimeStamp* time);
-
-  void CalculateVsyncParametersLockHeld(const CVTimeStamp* time);
-
-  // Prevent from spinning on CGLFlushDrawable when it fails to throttle to
-  // VSync frequency.
-  void RateLimitDraws();
-
-  void StartOrContinueDisplayLink();
-  void StopDisplayLink();
-
-  // Copy current frame to |target| video frame. This method must be called
-  // within a CGL context. Returns a callback that should be called outside
-  // of the CGL context.
-  // If |called_within_draw| is true this method is called within a drawing
-  // operations. This allow certain optimizations.
-  base::Closure CopyToVideoFrameWithinContext(
-      const gfx::Rect& src_subrect,
-      bool called_within_draw,
-      const scoped_refptr<media::VideoFrame>& target,
-      const base::Callback<void(bool)>& callback);
-
-  // Common GPU-readback copy path.  Only one of |bitmap_output| or
-  // |video_frame_output| may be specified: Either ARGB is written to
-  // |bitmap_output| or letter-boxed YV12 is written to |video_frame_output|.
-  base::Closure CopyToSelectedOutputWithinContext(
-      const gfx::Rect& src_pixel_subrect,
-      const gfx::Rect& dst_pixel_rect,
-      bool called_within_draw,
-      const SkBitmap* bitmap_output,
-      const scoped_refptr<media::VideoFrame>& video_frame_output,
-      const base::Callback<void(bool)>& done_callback);
-
-  // TODO(hclam): These two methods should be static.
-  void AsynchronousReadbackForCopy(
-      const gfx::Rect& dst_pixel_rect,
-      bool called_within_draw,
-      CopyContext* copy_context,
-      const SkBitmap* bitmap_output,
-      const scoped_refptr<media::VideoFrame>& video_frame_output);
-  bool SynchronousReadbackForCopy(
-      const gfx::Rect& dst_pixel_rect,
-      CopyContext* copy_context,
-      const SkBitmap* bitmap_output,
-      const scoped_refptr<media::VideoFrame>& video_frame_output);
-
-  // Scan the list of started asynchronous copies and test if each one has
-  // completed. If |block_until_finished| is true, then block until all
-  // pending copies are finished.
-  void CheckIfAllCopiesAreFinished(bool block_until_finished);
-  void CheckIfAllCopiesAreFinishedWithinContext(
-      bool block_until_finished,
-      std::vector<base::Closure>* done_callbacks);
-
-  void FailAllCopies();
-  void DestroyAllCopyContextsWithinContext();
-
   // Check for GL errors and store the result in error_. Only return new
   // errors
   GLenum GetAndSaveGLError();
 
-  gfx::Rect IntersectWithIOSurface(const gfx::Rect& rect) const;
-
-  // Cached pointer to IOSurfaceSupport Singleton.
-  IOSurfaceSupport* io_surface_support_;
-
-  // GL context, and parameters for context sharing. This may change when
-  // moving between windows, but will never be NULL.
-  scoped_refptr<CompositingIOSurfaceContext> context_;
+  // Offscreen context used for all operations other than drawing to the
+  // screen. This is in the same share group as the contexts used for
+  // drawing, and is the same for all IOSurfaces in all windows.
+  scoped_refptr<CompositingIOSurfaceContext> offscreen_context_;
 
   // IOSurface data.
-  uint64 io_surface_handle_;
-  base::ScopedCFTypeRef<CFTypeRef> io_surface_;
+  IOSurfaceID io_surface_handle_;
+  base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
 
   // The width and height of the io surface.
   gfx::Size pixel_io_surface_size_;  // In pixels.
@@ -326,38 +207,28 @@ class CompositingIOSurfaceMac {
   // with it.
   GLuint texture_;
 
-  // A pool of CopyContexts with OpenGL objects ready for re-use.  Prefer to
-  // pull one from the pool before creating a new CopyContext.
-  std::vector<CopyContext*> copy_context_pool_;
-
-  // CopyContexts being used for in-flight copy operations.
-  std::deque<CopyContext*> copy_requests_;
-
-  // Timer for finishing a copy operation.
-  base::Timer finish_copy_timer_;
-
-  // CVDisplayLink for querying Vsync timing info and throttling swaps.
-  CVDisplayLinkRef display_link_;
-
-  // Timer for stopping display link after a timeout with no swaps.
-  base::DelayTimer<CompositingIOSurfaceMac> display_link_stop_timer_;
-
-  // Lock for sharing data between UI thread and display-link thread.
-  base::Lock lock_;
-
-  // Vsync timing data.
-  base::TimeTicks vsync_timebase_;
-  uint32 vsync_interval_numerator_;
-  uint32 vsync_interval_denominator_;
-
-  bool initialized_is_intel_;
-  bool is_intel_;
-  GLint screen_;
-
   // Error saved by GetAndSaveGLError
   GLint gl_error_;
 
-  ui::LatencyInfo latency_info_;
+  // Aggressive IOSurface eviction logic. When using CoreAnimation, IOSurfaces
+  // are used only transiently to transfer from the GPU process to the browser
+  // process. Once the IOSurface has been drawn to its CALayer, the CALayer
+  // will not need updating again until its view is hidden and re-shown.
+  // Aggressively evict surfaces when more than 8 (the number allowed by the
+  // memory manager for fast tab switching) are allocated.
+  enum {
+    kMaximumUnevictedSurfaces = 8,
+  };
+  typedef std::list<CompositingIOSurfaceMac*> EvictionQueue;
+  void EvictionMarkUpdated();
+  void EvictionMarkEvicted();
+  EvictionQueue::iterator eviction_queue_iterator_;
+  bool eviction_has_been_drawn_since_updated_;
+
+  static void EvictionScheduleDoEvict();
+  static void EvictionDoEvict();
+  static base::LazyInstance<EvictionQueue> eviction_queue_;
+  static bool eviction_scheduled_;
 };
 
 }  // namespace content