Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10903)

Unified Diff: content/browser/renderer_host/compositing_iosurface_layer_mac.mm

Issue 394883007: Mac: Shift more code into C++ classes from ObjC classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@flip_fix
Patch Set: Touch-ups Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/compositing_iosurface_layer_mac.mm
diff --git a/content/browser/renderer_host/compositing_iosurface_layer_mac.mm b/content/browser/renderer_host/compositing_iosurface_layer_mac.mm
index 040d8f9fb8e1de21351a3ddcd044286c1bc633a4..724e56c9ff7dc292c433b46c3e3a0e763e84784d 100644
--- a/content/browser/renderer_host/compositing_iosurface_layer_mac.mm
+++ b/content/browser/renderer_host/compositing_iosurface_layer_mac.mm
@@ -17,29 +17,90 @@
#include "ui/gfx/size_conversions.h"
#include "ui/gl/gpu_switching_manager.h"
-@interface CompositingIOSurfaceLayer(Private)
-- (void)immediatelyForceDisplayAndAck;
-- (void)ackPendingFrame:(bool)success;
-- (void)timerFired;
-@end
+////////////////////////////////////////////////////////////////////////////////
+// CompositingIOSurfaceLayerHelper
namespace content {
-// The base::DelayTimer needs a C++ class to operate on, rather than Objective C
-// class. This helper class provides a bridge between the two.
-class CompositingIOSurfaceLayerHelper {
- public:
- CompositingIOSurfaceLayerHelper(CompositingIOSurfaceLayer* layer)
- : layer_(layer) {}
- void TimerFired() {
- [layer_ timerFired];
+CompositingIOSurfaceLayerHelper::CompositingIOSurfaceLayerHelper(
+ CompositingIOSurfaceLayerClient* client,
+ CompositingIOSurfaceLayer* layer)
+ : client_(client),
+ layer_(layer),
+ has_pending_frame_(false),
+ did_not_draw_counter_(0),
+ timer_(
+ FROM_HERE,
+ base::TimeDelta::FromSeconds(1) / 6,
+ this,
+ &CompositingIOSurfaceLayerHelper::TimerFired) {}
+
+CompositingIOSurfaceLayerHelper::~CompositingIOSurfaceLayerHelper() {
+ // Any acks that were waiting on this layer to draw will not occur, so ack
+ // them now to prevent blocking the renderer.
+ AckPendingFrame(true);
+}
+
+void CompositingIOSurfaceLayerHelper::GotNewFrame() {
+ has_pending_frame_ = true;
+ timer_.Reset();
+ // A trace value of 2 indicates that there is a pending swap ack. See
+ // canDrawInCGLContext for other value meanings.
+ TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 2);
+}
+
+void CompositingIOSurfaceLayerHelper::CanDrawCalled(bool needs_display) {
+ // If we return NO 30 times in a row, switch to being synchronous to avoid
+ // burning CPU cycles on this callback.
+ if (needs_display) {
+ did_not_draw_counter_ = 0;
miu 2014/07/16 22:31:56 Seems like this should only be set to zero when se
ccameron 2014/07/17 02:30:02 This is a bit easier to reason about correctness,
+ } else {
+ did_not_draw_counter_ += 1;
+ if (did_not_draw_counter_ > 30)
miu 2014/07/16 22:31:55 Consider making this: if (did_not_draw_counter_
ccameron 2014/07/17 02:30:02 Good idea -- done.
+ [layer_ setAsynchronous:NO];
}
- private:
- CompositingIOSurfaceLayer* layer_;
-};
+
+ // Add an instantaneous blip to the PendingSwapAck state to indicate
+ // that CoreAnimation asked if a frame is ready. A blip up to to 3 (usually
+ // from 2, indicating that a swap ack is pending) indicates that we
+ // requested a draw. A blip up to 1 (usually from 0, indicating there is no
+ // pending swap ack) indicates that we did not request a draw. This would
+ // be more natural to do with a tracing pseudo-thread
+ // http://crbug.com/366300
+ TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, needs_display ? 3 : 1);
+ TRACE_COUNTER_ID1("browser", "PendingSwapAck", this,
+ has_pending_frame_ ? 2 : 0);
+}
+
+void CompositingIOSurfaceLayerHelper::AckPendingFrame(bool success) {
+ if (!has_pending_frame_)
+ return;
+ has_pending_frame_ = false;
+ client_->AcceleratedLayerDidDrawFrame(success);
+ // A trace value of 0 indicates that there is no longer a pending swap ack.
+ TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 0);
+}
+
+void CompositingIOSurfaceLayerHelper::ImmediatelyForceDisplayAndAck() {
+ [layer_ setNeedsDisplay];
+ [layer_ displayIfNeeded];
+
+ // Calls to setNeedsDisplay can sometimes be ignored, especially if issued
+ // rapidly (e.g, with vsync off). This is unacceptable because the failure
+ // to ack a single frame will hang the renderer. Ensure that the renderer
+ // not be blocked by lying and claiming that we drew the frame.
+ AckPendingFrame(true);
+}
+
+void CompositingIOSurfaceLayerHelper::TimerFired() {
+ ImmediatelyForceDisplayAndAck();
+}
} // namespace content
+////////////////////////////////////////////////////////////////////////////////
+// CompositingIOSurfaceLayer
+
@implementation CompositingIOSurfaceLayer
- (content::CompositingIOSurfaceMac*)iosurface {
@@ -55,21 +116,12 @@ class CompositingIOSurfaceLayerHelper {
withScaleFactor:(float)scale_factor
withClient:(content::CompositingIOSurfaceLayerClient*)client {
if (self = [super init]) {
- iosurface_ = iosurface;
- client_ = client;
- helper_.reset(new content::CompositingIOSurfaceLayerHelper(self));
- timer_.reset(new base::DelayTimer<content::CompositingIOSurfaceLayerHelper>(
- FROM_HERE,
- base::TimeDelta::FromSeconds(1) / 6,
- helper_.get(),
- &content::CompositingIOSurfaceLayerHelper::TimerFired));
+ helper_.reset(new content::CompositingIOSurfaceLayerHelper(client, self));
+ iosurface_ = iosurface;
context_ = content::CompositingIOSurfaceContext::Get(
content::CompositingIOSurfaceContext::kCALayerContextWindowNumber);
DCHECK(context_);
- needs_display_ = NO;
miu 2014/07/16 22:31:56 I think you meant to keep this statement. But, if
ccameron 2014/07/17 02:30:02 Moved it to the C++ class.
- has_pending_frame_ = NO;
- did_not_draw_counter_ = 0;
[self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
[self setAnchorPoint:CGPointMake(0, 0)];
@@ -83,25 +135,22 @@ class CompositingIOSurfaceLayerHelper {
return self;
}
+- (void)dealloc {
+ DCHECK(!helper_);
+ [super dealloc];
+}
+
- (void)resetClient {
- // Any acks that were waiting on this layer to draw will not occur, so ack
- // them now to prevent blocking the renderer.
- [self ackPendingFrame:true];
- client_ = NULL;
+ helper_.reset();
}
- (void)gotNewFrame {
- has_pending_frame_ = YES;
- timer_->Reset();
-
- // A trace value of 2 indicates that there is a pending swap ack. See
- // canDrawInCGLContext for other value meanings.
- TRACE_COUNTER_ID1("browser", "PendingSwapAck", self, 2);
+ helper_->GotNewFrame();
if (context_ && context_->is_vsync_disabled()) {
// If vsync is disabled, draw immediately and don't bother trying to use
// the isAsynchronous property to ensure smooth animation.
- [self immediatelyForceDisplayAndAck];
+ helper_->ImmediatelyForceDisplayAndAck();
} else {
needs_display_ = YES;
if (![self isAsynchronous])
miu 2014/07/16 22:31:55 This should be moved into the helper. That way, a
ccameron 2014/07/17 02:30:02 You're right -- moved it to the helper.
@@ -109,34 +158,6 @@ class CompositingIOSurfaceLayerHelper {
}
}
-// Private methods:
-
-- (void)immediatelyForceDisplayAndAck {
- [self setNeedsDisplay];
- [self displayIfNeeded];
-
- // Calls to setNeedsDisplay can sometimes be ignored, especially if issued
- // rapidly (e.g, with vsync off). This is unacceptable because the failure
- // to ack a single frame will hang the renderer. Ensure that the renderer
- // not be blocked by lying and claiming that we drew the frame.
- [self ackPendingFrame:true];
-}
-
-- (void)ackPendingFrame:(bool)success {
- if (!has_pending_frame_)
- return;
-
- TRACE_COUNTER_ID1("browser", "PendingSwapAck", self, 0);
- has_pending_frame_ = NO;
- if (client_)
- client_->AcceleratedLayerDidDrawFrame(success);
-}
-
-- (void)timerFired {
- if (has_pending_frame_)
- [self immediatelyForceDisplayAndAck];
-}
-
// The remaining methods implement the CAOpenGLLayer interface.
- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
@@ -160,27 +181,8 @@ class CompositingIOSurfaceLayerHelper {
pixelFormat:(CGLPixelFormatObj)pixelFormat
forLayerTime:(CFTimeInterval)timeInterval
displayTime:(const CVTimeStamp*)timeStamp {
- // Add an instantaneous blip to the PendingSwapAck state to indicate
- // that CoreAnimation asked if a frame is ready. A blip up to to 3 (usually
- // from 2, indicating that a swap ack is pending) indicates that we requested
- // a draw. A blip up to 1 (usually from 0, indicating there is no pending swap
- // ack) indicates that we did not request a draw. This would be more natural
- // to do with a tracing pseudo-thread
- // http://crbug.com/366300
- TRACE_COUNTER_ID1("browser", "PendingSwapAck", self, needs_display_ ? 3 : 1);
- TRACE_COUNTER_ID1("browser", "PendingSwapAck", self,
- has_pending_frame_ ? 2 : 0);
-
- // If we return NO 30 times in a row, switch to being synchronous to avoid
- // burning CPU cycles on this callback.
- if (needs_display_) {
- did_not_draw_counter_ = 0;
- } else {
- did_not_draw_counter_ += 1;
- if (did_not_draw_counter_ > 30)
- [self setAsynchronous:NO];
- }
-
+ if (helper_)
+ helper_->CanDrawCalled(needs_display_);
return needs_display_;
}
@@ -211,7 +213,8 @@ class CompositingIOSurfaceLayerHelper {
bool draw_succeeded = iosurface_->DrawIOSurface(
context_, window_rect, window_scale_factor);
- [self ackPendingFrame:draw_succeeded];
+ if (helper_)
+ helper_->AckPendingFrame(draw_succeeded);
needs_display_ = NO;
[super drawInCGLContext:glContext

Powered by Google App Engine
This is Rietveld 408576698