1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#import <Cocoa/Cocoa.h>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/mac/scoped_cftyperef.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/ref_counted.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/timer/timer.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/gfx/size.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci@class IOSurfaceLayer;
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content {
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CompositingIOSurfaceMac;
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CompositingIOSurfaceContext;
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The interface through which the IOSurfaceLayer calls back into
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// the structrue that created it (RenderWidgetHostViewMac or
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// BrowserCompositorViewMac).
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass IOSurfaceLayerClient {
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Used to indicate that the layer should attempt to draw immediately and
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // should (even if the draw is elided by the system), ack the frame
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // immediately.
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool IOSurfaceLayerShouldAckImmediately() const = 0;
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Called when a frame is drawn or when, because the layer is not visible, it
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // is known that the frame will never drawn.
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void IOSurfaceLayerDidDrawFrame() = 0;
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Called when an error prevents the frame from being drawn.
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void IOSurfaceLayerHitError() = 0;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// IOSurfaceLayerHelper provides C++ functionality needed for the
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// IOSurfaceLayer class, and does most of the heavy lifting for the
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// class.
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(ccameron): This class should own IOSurfaceLayer, rather than
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// vice versa.
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass IOSurfaceLayerHelper {
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  IOSurfaceLayerHelper(IOSurfaceLayerClient* client,
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  IOSurfaceLayer* layer);
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ~IOSurfaceLayerHelper();
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called when the IOSurfaceLayer gets a new frame.
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void GotNewFrame();
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called whenever -[IOSurfaceLayer setNeedsDisplay] is called.
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetNeedsDisplay();
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called whenever -[IOSurfaceLayer canDrawInCGLContext] is called,
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to determine if a new frame should be drawn.
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool CanDraw();
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called whenever -[IOSurfaceLayer drawInCGLContext] draws a
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // frame.
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void DidDraw(bool success);
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Immediately re-draw the layer, even if the content has not changed, and
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // ensure that the frame be acked.
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void SetNeedsDisplayAndDisplayAndAck();
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Immediately draw the layer, only if one is pending, and ensure that the
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // frame be acked.
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void DisplayIfNeededAndAck();
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Mark a bracket in which new frames are being pumped in a restricted nested
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // run loop. During this time frames are acked immediately and draws are
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // deferred until the bracket ends.
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void BeginPumpingFrames();
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void EndPumpingFrames();
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Called whenever the frame provided in GotNewFrame should be acknowledged
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // (this may be because it was drawn, or it may be to unblock the
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // compositor).
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void AckPendingFrame(bool success);
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void TimerFired();
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The client that the owning layer was created with.
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::IOSurfaceLayerClient* const client_;
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The layer that owns this helper.
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  IOSurfaceLayer* const layer_;
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Used to track when canDrawInCGLContext should return YES. This can be
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in response to receiving a new compositor frame, or from any of the events
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // that cause setNeedsDisplay to be called on the layer.
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool needs_display_;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // This is set when a frame is received, and un-set when the frame is drawn.
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool has_pending_frame_;
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Incremented every time that this layer is asked to draw but does not have
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // new content to draw.
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint64 did_not_draw_counter_;
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Set when inside a BeginPumpingFrames/EndPumpingFrames block.
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool is_pumping_frames_;
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The browser places back-pressure on the GPU by not acknowledging swap
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // calls until they appear on the screen. This can lead to hangs if the
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // view is moved offscreen (among other things). Prevent hangs by always
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // acknowledging the frame after timeout of 1/6th of a second  has passed.
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::DelayTimer<IOSurfaceLayerHelper> timer_;
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// The CoreAnimation layer for drawing accelerated content.
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci@interface IOSurfaceLayer : CAOpenGLLayer {
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch @private
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<content::CompositingIOSurfaceMac> iosurface_;
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<content::CompositingIOSurfaceContext> context_;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<content::IOSurfaceLayerHelper> helper_;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci- (id)initWithClient:(content::IOSurfaceLayerClient*)client
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     withScaleFactor:(float)scale_factor;
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci- (bool)gotFrameWithIOSurface:(IOSurfaceID)io_surface_id
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                withPixelSize:(gfx::Size)pixel_size
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              withScaleFactor:(float)scale_factor;
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Context poison accessors.
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci- (void)poisonContextAndSharegroup;
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci- (bool)hasBeenPoisoned;
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci- (float)scaleFactor;
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The CGL renderer ID.
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci- (int)rendererID;
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Mark that the client is no longer valid and cannot be called back into. This
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// must be called before the layer is destroyed.
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)- (void)resetClient;
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Called when a new frame is received.
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)- (void)gotNewFrame;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Force a draw immediately (even if this means re-displaying a previously
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// displayed frame).
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)- (void)setNeedsDisplayAndDisplayAndAck;
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Force a draw immediately, but only if one was requested.
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)- (void)displayIfNeededAndAck;
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Mark a bracket in which new frames are being pumped in a restricted nested
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// run loop.
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)- (void)beginPumpingFrames;
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)- (void)endPumpingFrames;
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)@end
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_
162