Commit 672e23e9 authored by ccameron's avatar ccameron Committed by Commit bot

Simplify IOSurface CoreAnimation code: Part 2

It isn't necessary to mess around with sharing CGLContextObjs anymore,
they were necessary only to share data between the frame subscriber
and the RenderWidgetHostViewMac. Just give each IOSurfaceLayer its
own CGLContextObj, and draw using immediate mode (using shaders
resulted in an increase in startup time).

BUG=314190
TBR=pfeldman@chromium.org
R=kbr@chromium.org

Review URL: https://codereview.chromium.org/490393002

Cr-Commit-Position: refs/heads/master@{#293103}
parent 483aa08b
...@@ -208,7 +208,6 @@ void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( ...@@ -208,7 +208,6 @@ void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
// layer. // layer.
bool needs_new_layer = bool needs_new_layer =
!io_surface_layer_ || !io_surface_layer_ ||
[io_surface_layer_ hasBeenPoisoned] ||
[io_surface_layer_ scaleFactor] != scale_factor; [io_surface_layer_ scaleFactor] != scale_factor;
if (needs_new_layer) { if (needs_new_layer) {
io_surface_layer_.reset( io_surface_layer_.reset(
...@@ -221,28 +220,12 @@ void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( ...@@ -221,28 +220,12 @@ void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
} }
// Open the provided IOSurface. // Open the provided IOSurface.
if (io_surface_layer_) { [io_surface_layer_ gotFrameWithIOSurface:io_surface_id
bool result = [io_surface_layer_ gotFrameWithIOSurface:io_surface_id withPixelSize:pixel_size
withPixelSize:pixel_size withScaleFactor:scale_factor];
withScaleFactor:scale_factor];
if (!result) {
DestroyIOSurfaceLayer(io_surface_layer_);
LOG(ERROR) << "Failed open IOSurface in IOSurfaceLayer";
}
}
// Give a final complaint if anything with the layer's creation went wrong.
// This frame will appear blank, the compositor will try to create another,
// and maybe that will go better.
if (!io_surface_layer_) {
LOG(ERROR) << "IOSurfaceLayer is nil, tab will be blank";
IOSurfaceLayerHitError();
}
// Make the CALayer draw and set its size appropriately. // Make the CALayer draw and set its size appropriately.
if (io_surface_layer_) { if (io_surface_layer_) {
[io_surface_layer_ gotNewFrame];
// Set the bounds of the accelerated layer to match the size of the frame. // Set the bounds of the accelerated layer to match the size of the frame.
// If the bounds changed, force the content to be displayed immediately. // If the bounds changed, force the content to be displayed immediately.
CGRect new_layer_bounds = CGRectMake( CGRect new_layer_bounds = CGRectMake(
...@@ -345,12 +328,8 @@ void BrowserCompositorViewMacInternal::IOSurfaceLayerDidDrawFrame() { ...@@ -345,12 +328,8 @@ void BrowserCompositorViewMacInternal::IOSurfaceLayerDidDrawFrame() {
} }
void BrowserCompositorViewMacInternal::IOSurfaceLayerHitError() { void BrowserCompositorViewMacInternal::IOSurfaceLayerHitError() {
// Perform all acks that would have been done if the frame had succeeded, to
// un-block the compositor and renderer.
IOSurfaceLayerDidDrawFrame();
// Poison the context being used and request a mulligan. // Poison the context being used and request a mulligan.
[io_surface_layer_ poisonContextAndSharegroup]; DestroyIOSurfaceLayer(io_surface_layer_);
compositor_->ScheduleFullRedraw(); compositor_->ScheduleFullRedraw();
} }
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_ #ifndef CONTENT_BROWSER_COMPOSITOR_IO_SURFACE_LAYER_MAC_H_
#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_ #define CONTENT_BROWSER_COMPOSITOR_IO_SURFACE_LAYER_MAC_H_
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#include <IOSurface/IOSurfaceAPI.h>
#include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_cftyperef.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
...@@ -15,8 +16,7 @@ ...@@ -15,8 +16,7 @@
@class IOSurfaceLayer; @class IOSurfaceLayer;
namespace content { namespace content {
class CompositingIOSurfaceMac; class IOSurfaceLayerHelper;
class CompositingIOSurfaceContext;
// The interface through which the IOSurfaceLayer calls back into // The interface through which the IOSurfaceLayer calls back into
// the structrue that created it (RenderWidgetHostViewMac or // the structrue that created it (RenderWidgetHostViewMac or
...@@ -36,58 +36,13 @@ class IOSurfaceLayerClient { ...@@ -36,58 +36,13 @@ class IOSurfaceLayerClient {
virtual void IOSurfaceLayerHitError() = 0; virtual void IOSurfaceLayerHitError() = 0;
}; };
// IOSurfaceLayerHelper provides C++ functionality needed for the } // namespace content
// 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();
// 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. // The CoreAnimation layer for drawing accelerated content.
IOSurfaceLayer* const layer_; @interface IOSurfaceLayer : CAOpenGLLayer {
@private
content::IOSurfaceLayerClient* client_;
scoped_ptr<content::IOSurfaceLayerHelper> helper_;
// Used to track when canDrawInCGLContext should return YES. This can be // 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 // in response to receiving a new compositor frame, or from any of the events
...@@ -104,35 +59,30 @@ class IOSurfaceLayerHelper { ...@@ -104,35 +59,30 @@ class IOSurfaceLayerHelper {
// Set when inside a BeginPumpingFrames/EndPumpingFrames block. // Set when inside a BeginPumpingFrames/EndPumpingFrames block.
bool is_pumping_frames_; bool is_pumping_frames_;
// The browser places back-pressure on the GPU by not acknowledging swap // The IOSurface being drawn by this layer.
// calls until they appear on the screen. This can lead to hangs if the base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
// 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_;
};
} // namespace content // 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_;
// The CoreAnimation layer for drawing accelerated content. // The GL texture that is bound to |io_surface_|. If |io_surface_| changes,
@interface IOSurfaceLayer : CAOpenGLLayer { // then this is marked as dirty by setting |io_surface_texture_dirty_|.
@private GLuint io_surface_texture_;
scoped_refptr<content::CompositingIOSurfaceMac> iosurface_; bool io_surface_texture_dirty_;
scoped_refptr<content::CompositingIOSurfaceContext> context_;
scoped_ptr<content::IOSurfaceLayerHelper> helper_; // The CGL renderer ID, captured at draw time.
GLint cgl_renderer_id_;
} }
- (id)initWithClient:(content::IOSurfaceLayerClient*)client - (id)initWithClient:(content::IOSurfaceLayerClient*)client
withScaleFactor:(float)scale_factor; withScaleFactor:(float)scale_factor;
- (bool)gotFrameWithIOSurface:(IOSurfaceID)io_surface_id // Called when a new frame is received.
- (void)gotFrameWithIOSurface:(IOSurfaceID)io_surface_id
withPixelSize:(gfx::Size)pixel_size withPixelSize:(gfx::Size)pixel_size
withScaleFactor:(float)scale_factor; withScaleFactor:(float)scale_factor;
// Context poison accessors.
- (void)poisonContextAndSharegroup;
- (bool)hasBeenPoisoned;
- (float)scaleFactor; - (float)scaleFactor;
// The CGL renderer ID. // The CGL renderer ID.
...@@ -142,20 +92,14 @@ class IOSurfaceLayerHelper { ...@@ -142,20 +92,14 @@ class IOSurfaceLayerHelper {
// must be called before the layer is destroyed. // must be called before the layer is destroyed.
- (void)resetClient; - (void)resetClient;
// Called when a new frame is received.
- (void)gotNewFrame;
// Force a draw immediately (even if this means re-displaying a previously // Force a draw immediately (even if this means re-displaying a previously
// displayed frame). // displayed frame).
- (void)setNeedsDisplayAndDisplayAndAck; - (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 // Mark a bracket in which new frames are being pumped in a restricted nested
// run loop. // run loop.
- (void)beginPumpingFrames; - (void)beginPumpingFrames;
- (void)endPumpingFrames; - (void)endPumpingFrames;
@end @end
#endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_ #endif // CONTENT_BROWSER_COMPOSITOR_IO_SURFACE_LAYER_MAC_H_
...@@ -125,9 +125,9 @@ IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, MAYBE_CaptureScreenshot) { ...@@ -125,9 +125,9 @@ IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, MAYBE_CaptureScreenshot) {
gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(png.data()), gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(png.data()),
png.size(), &bitmap); png.size(), &bitmap);
SkColor color(bitmap.getColor(0, 0)); SkColor color(bitmap.getColor(0, 0));
EXPECT_TRUE(std::abs(0x12-(int)SkColorGetR(color)) <= 1); EXPECT_LE(std::abs(0x12-(int)SkColorGetR(color)), 1);
EXPECT_TRUE(std::abs(0x34-(int)SkColorGetG(color)) <= 1); EXPECT_LE(std::abs(0x34-(int)SkColorGetG(color)), 1);
EXPECT_TRUE(std::abs(0x56-(int)SkColorGetB(color)) <= 1); EXPECT_LE(std::abs(0x56-(int)SkColorGetB(color)), 1);
} }
} // namespace content } // namespace content
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment