Index: content/browser/compositor/io_surface_layer_mac.h |
diff --git a/content/browser/compositor/io_surface_layer_mac.h b/content/browser/compositor/io_surface_layer_mac.h |
index 7ed5d0927d68c85ae179dabf8875e8def8fcccdd..83a6e43640b3a752d2e6124bf1dea7bb2dda6dac 100644 |
--- a/content/browser/compositor/io_surface_layer_mac.h |
+++ b/content/browser/compositor/io_surface_layer_mac.h |
@@ -2,22 +2,21 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#ifndef CONTENT_BROWSER_COMPOSITOR_IO_SURFACE_LAYER_MAC_H_ |
-#define CONTENT_BROWSER_COMPOSITOR_IO_SURFACE_LAYER_MAC_H_ |
+#ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_ |
+#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_ |
#import <Cocoa/Cocoa.h> |
-#include <IOSurface/IOSurfaceAPI.h> |
#include "base/mac/scoped_cftyperef.h" |
#include "base/memory/ref_counted.h" |
#include "base/timer/timer.h" |
#include "ui/gfx/size.h" |
-#include "ui/gl/scoped_cgl.h" |
@class IOSurfaceLayer; |
namespace content { |
-class IOSurfaceLayerHelper; |
+class CompositingIOSurfaceMac; |
+class CompositingIOSurfaceContext; |
// The interface through which the IOSurfaceLayer calls back into |
// the structrue that created it (RenderWidgetHostViewMac or |
@@ -37,13 +36,58 @@ class IOSurfaceLayerClient { |
virtual void IOSurfaceLayerHitError() = 0; |
}; |
-} // namespace content |
+// IOSurfaceLayerHelper provides C++ functionality needed for the |
+// IOSurfaceLayer class, and does most of the heavy lifting for the |
+// class. |
+// TODO(ccameron): This class should own IOSurfaceLayer, rather than |
+// vice versa. |
+class IOSurfaceLayerHelper { |
+ public: |
+ IOSurfaceLayerHelper(IOSurfaceLayerClient* client, |
+ IOSurfaceLayer* layer); |
+ ~IOSurfaceLayerHelper(); |
-// The CoreAnimation layer for drawing accelerated content. |
-@interface IOSurfaceLayer : CAOpenGLLayer { |
- @private |
- content::IOSurfaceLayerClient* client_; |
- scoped_ptr<content::IOSurfaceLayerHelper> helper_; |
+ // Called when the IOSurfaceLayer gets a new frame. |
+ void GotNewFrame(); |
+ |
+ // Called whenever -[IOSurfaceLayer setNeedsDisplay] is called. |
+ void SetNeedsDisplay(); |
+ |
+ // Called whenever -[IOSurfaceLayer canDrawInCGLContext] is called, |
+ // to determine if a new frame should be drawn. |
+ bool CanDraw(); |
+ |
+ // Called whenever -[IOSurfaceLayer drawInCGLContext] draws a |
+ // frame. |
+ void DidDraw(bool success); |
+ |
+ // Immediately re-draw the layer, even if the content has not changed, and |
+ // ensure that the frame be acked. |
+ void SetNeedsDisplayAndDisplayAndAck(); |
+ |
+ // Immediately draw the layer, only if one is pending, and ensure that the |
+ // frame be acked. |
+ void DisplayIfNeededAndAck(); |
+ |
+ // Mark a bracket in which new frames are being pumped in a restricted nested |
+ // run loop. During this time frames are acked immediately and draws are |
+ // deferred until the bracket ends. |
+ void BeginPumpingFrames(); |
+ void EndPumpingFrames(); |
+ |
+ private: |
+ // Called whenever the frame provided in GotNewFrame should be acknowledged |
+ // (this may be because it was drawn, or it may be to unblock the |
+ // compositor). |
+ void AckPendingFrame(bool success); |
+ |
+ void TimerFired(); |
+ |
+ // The client that the owning layer was created with. |
+ content::IOSurfaceLayerClient* const client_; |
+ |
+ // The layer that owns this helper. |
+ IOSurfaceLayer* const layer_; |
// Used to track when canDrawInCGLContext should return YES. This can be |
// in response to receiving a new compositor frame, or from any of the events |
@@ -60,32 +104,35 @@ class IOSurfaceLayerClient { |
// Set when inside a BeginPumpingFrames/EndPumpingFrames block. |
bool is_pumping_frames_; |
- // The IOSurface being drawn by this layer. |
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; |
+ // The browser places back-pressure on the GPU by not acknowledging swap |
+ // calls until they appear on the screen. This can lead to hangs if the |
+ // view is moved offscreen (among other things). Prevent hangs by always |
+ // acknowledging the frame after timeout of 1/6th of a second has passed. |
+ base::DelayTimer<IOSurfaceLayerHelper> timer_; |
+}; |
- // The size of the frame in pixels. This will be less or equal than the pixel |
- // size of |io_surface_|. |
- gfx::Size frame_pixel_size_; |
+} // namespace content |
- // The GL texture that was bound to |io_surface_| during the last draw call, |
- // along with the context that was done in, and the value of |io_surface_| at |
- // the time of the bind. |
- GLuint io_surface_texture_; |
- base::ScopedTypeRef<CGLContextObj> io_surface_texture_context_; |
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface_texture_io_surface_; |
+// The CoreAnimation layer for drawing accelerated content. |
+@interface IOSurfaceLayer : CAOpenGLLayer { |
+ @private |
+ scoped_refptr<content::CompositingIOSurfaceMac> iosurface_; |
+ scoped_refptr<content::CompositingIOSurfaceContext> context_; |
- // The CGL renderer ID, captured at draw time. |
- GLint cgl_renderer_id_; |
+ scoped_ptr<content::IOSurfaceLayerHelper> helper_; |
} |
- (id)initWithClient:(content::IOSurfaceLayerClient*)client |
withScaleFactor:(float)scale_factor; |
-// Called when a new frame is received. |
-- (void)gotFrameWithIOSurface:(IOSurfaceID)io_surface_id |
+- (bool)gotFrameWithIOSurface:(IOSurfaceID)io_surface_id |
withPixelSize:(gfx::Size)pixel_size |
withScaleFactor:(float)scale_factor; |
+// Context poison accessors. |
+- (void)poisonContextAndSharegroup; |
+- (bool)hasBeenPoisoned; |
+ |
- (float)scaleFactor; |
// The CGL renderer ID. |
@@ -95,14 +142,20 @@ class IOSurfaceLayerClient { |
// must be called before the layer is destroyed. |
- (void)resetClient; |
+// Called when a new frame is received. |
+- (void)gotNewFrame; |
+ |
// Force a draw immediately (even if this means re-displaying a previously |
// displayed frame). |
- (void)setNeedsDisplayAndDisplayAndAck; |
+// Force a draw immediately, but only if one was requested. |
+- (void)displayIfNeededAndAck; |
+ |
// Mark a bracket in which new frames are being pumped in a restricted nested |
// run loop. |
- (void)beginPumpingFrames; |
- (void)endPumpingFrames; |
@end |
-#endif // CONTENT_BROWSER_COMPOSITOR_IO_SURFACE_LAYER_MAC_H_ |
+#endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_ |