Changeset 222961 in webkit


Ignore:
Timestamp:
Oct 5, 2017 11:37:16 PM (6 years ago)
Author:
dino@apple.com
Message:

Lots of missing frames in YouTube360 when fullscreen on MacBook
https://bugs.webkit.org/show_bug.cgi?id=177903
<rdar://problem/33273300>

Reviewed by Sam Weinig.

Source/WebCore:

Our compositing path for WebGL on macOS was too slow, requiring a copy
of the framebuffer into another GL context. Replace this by having
WebGL render into a texture that is backed by an IOSurface, and then
set the WebGLLayer to use the IOSurface as contents.

Covered by the existing WebGL tests.

  • platform/graphics/GraphicsContext3D.h:

(WebCore::GraphicsContext3D::platformTexture const): We no longer use the
framebuffer object outside the class, so change this to return the GL texture
that the framebuffer is rendering in to. It was kind-of strange that it was
named this way originally.
Also make endPaint available on macOS, and add the definitions for
createIOSurfaceBackingStore and updateFramebufferTextureBackingStoreFromLayer.

  • platform/graphics/cocoa/GraphicsContext3DCocoa.mm:

(WebCore::GraphicsContext3D::GraphicsContext3D): Now that we're using an IOSurface,
we're binding to a new attachment point, GL_TEXTURE_RECTANGLE.
(WebCore::GraphicsContext3D::endPaint): This is now being called on macOS and iOS,
so add a comment that explains the extra work that iOS needs to do. At some future
point it would be nice to make this slightly cleaner, so that iOS and macOS are
more similar.
(WebCore::GraphicsContext3D::allocateIOSurfaceBackingStore): New function that calls
into the corresponding WebGLLayer function.
(WebCore::GraphicsContext3D::updateFramebufferTextureBackingStoreFromLayer): Ditto.

  • platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:

(WebCore::wipeAlphaChannelFromPixels): Both readPixels and drawing a WebGL context
into another buffer need to fill out the alpha channel if this context was
created without one, otherwise the IOSurface backing store will happily provide
what might be non-zero values.
(WebCore::GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary): Call the helper above.
(WebCore::GraphicsContext3D::reshapeFBOs): Add more code to call into the macOS-specific
function to use an IOSurface as the framebuffer texture.
(WebCore::GraphicsContext3D::readPixels): Call the helper above.

  • platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:

(PlatformCALayerCocoa::copyContentsFromLayer): Replace the use of the
deprecated setContentsChanged with reloadValueForKeyPath.

  • platform/graphics/cocoa/WebGLLayer.h: The macOS implementation now

inherits from CALayer directly rather than CAOpenGLLayer. It also adds
a few member variables to handle the IOSurfaces used for triple buffering.

  • platform/graphics/cocoa/WebGLLayer.mm:

(-[WebGLLayer initWithGraphicsContext3D:]): If we were created without an
alpha channel, tell CA that we're an opaque layer. Also set the layer's transform
to identity, so that it calls into the code below to flip the contents.
(-[WebGLLayer setTransform:]): Because an IOSurface is used for the layer contents,
we don't get a chance to flip the drawing the way we do via the drawInContext delegate.
Instead we have to apply a scale(1, -1) transform on top of the layer transform to
make sure the layer is rendered right-way up.
(-[WebGLLayer setAnchorPoint:]): Ditto, except we have to assume the anchor point is
at the bottom of the layer, so flip the Y value.
(-[WebGLLayer display]): Swap between the drawing buffer and the contents buffer, and
then get a new buffer ready for display.
(createAppropriateIOSurface): Helper.
(-[WebGLLayer allocateIOSurfaceBackingStoreWithSize:usingAlpha:]): Initializes the
IOSurfaces used for drawing buffers.
(-[WebGLLayer bindFramebufferToNextAvailableSurface]): Take the next available IOSurface and
make it the drawing buffer (binding in to WebGL at the same time).
(-[WebGLLayer copyCGLPixelFormatForDisplayMask:]): Deleted.
(-[WebGLLayer copyCGLContextForPixelFormat:]): Deleted.
(-[WebGLLayer drawInCGLContext:pixelFormat:forLayerTime:displayTime:]): Deleted.

  • platform/graphics/mac/WebLayer.mm: Remove the definition of reloadValueForKeyPath.

Source/WebCore/PAL:

Add reloadValueForKeyPath to replace setContentsChanged on CALayer.

  • pal/spi/cocoa/QuartzCoreSPI.h:
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/TestExpectations

    r222921 r222961  
    15141514
    15151515webkit.org/b/177799 accessibility/table-detection.html [ Pass Failure ]
     1516
     1517webkit.org/b/177997 webgl/1.0.2/conformance/textures/copy-tex-image-2d-formats.html [ Pass Failure ]
  • trunk/Source/WebCore/ChangeLog

    r222960 r222961  
     12017-10-05  Dean Jackson  <dino@apple.com>
     2
     3        Lots of missing frames in YouTube360 when fullscreen on MacBook
     4        https://bugs.webkit.org/show_bug.cgi?id=177903
     5        <rdar://problem/33273300>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Our compositing path for WebGL on macOS was too slow, requiring a copy
     10        of the framebuffer into another GL context. Replace this by having
     11        WebGL render into a texture that is backed by an IOSurface, and then
     12        set the WebGLLayer to use the IOSurface as contents.
     13
     14        Covered by the existing WebGL tests.
     15
     16        * platform/graphics/GraphicsContext3D.h:
     17        (WebCore::GraphicsContext3D::platformTexture const): We no longer use the
     18        framebuffer object outside the class, so change this to return the GL texture
     19        that the framebuffer is rendering in to. It was kind-of strange that it was
     20        named this way originally.
     21        Also make endPaint available on macOS, and add the definitions for
     22        createIOSurfaceBackingStore and updateFramebufferTextureBackingStoreFromLayer.
     23
     24        * platform/graphics/cocoa/GraphicsContext3DCocoa.mm:
     25        (WebCore::GraphicsContext3D::GraphicsContext3D): Now that we're using an IOSurface,
     26        we're binding to a new attachment point, GL_TEXTURE_RECTANGLE.
     27        (WebCore::GraphicsContext3D::endPaint): This is now being called on macOS and iOS,
     28        so add a comment that explains the extra work that iOS needs to do. At some future
     29        point it would be nice to make this slightly cleaner, so that iOS and macOS are
     30        more similar.
     31        (WebCore::GraphicsContext3D::allocateIOSurfaceBackingStore): New function that calls
     32        into the corresponding WebGLLayer function.
     33        (WebCore::GraphicsContext3D::updateFramebufferTextureBackingStoreFromLayer): Ditto.
     34
     35        * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
     36        (WebCore::wipeAlphaChannelFromPixels): Both readPixels and drawing a WebGL context
     37        into another buffer need to fill out the alpha channel if this context was
     38        created without one, otherwise the IOSurface backing store will happily provide
     39        what might be non-zero values.
     40        (WebCore::GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary): Call the helper above.
     41        (WebCore::GraphicsContext3D::reshapeFBOs): Add more code to call into the macOS-specific
     42        function to use an IOSurface as the framebuffer texture.
     43        (WebCore::GraphicsContext3D::readPixels): Call the helper above.
     44
     45        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
     46        (PlatformCALayerCocoa::copyContentsFromLayer): Replace the use of the
     47        deprecated setContentsChanged with reloadValueForKeyPath.
     48
     49        * platform/graphics/cocoa/WebGLLayer.h: The macOS implementation now
     50        inherits from CALayer directly rather than CAOpenGLLayer. It also adds
     51        a few member variables to handle the IOSurfaces used for triple buffering.
     52
     53        * platform/graphics/cocoa/WebGLLayer.mm:
     54        (-[WebGLLayer initWithGraphicsContext3D:]): If we were created without an
     55        alpha channel, tell CA that we're an opaque layer. Also set the layer's transform
     56        to identity, so that it calls into the code below to flip the contents.
     57        (-[WebGLLayer setTransform:]): Because an IOSurface is used for the layer contents,
     58        we don't get a chance to flip the drawing the way we do via the drawInContext delegate.
     59        Instead we have to apply a scale(1, -1) transform on top of the layer transform to
     60        make sure the layer is rendered right-way up.
     61        (-[WebGLLayer setAnchorPoint:]): Ditto, except we have to assume the anchor point is
     62        at the bottom of the layer, so flip the Y value.
     63        (-[WebGLLayer display]): Swap between the drawing buffer and the contents buffer, and
     64        then get a new buffer ready for display.
     65        (createAppropriateIOSurface): Helper.
     66        (-[WebGLLayer allocateIOSurfaceBackingStoreWithSize:usingAlpha:]): Initializes the
     67        IOSurfaces used for drawing buffers.
     68        (-[WebGLLayer bindFramebufferToNextAvailableSurface]): Take the next available IOSurface and
     69        make it the drawing buffer (binding in to WebGL at the same time).
     70        (-[WebGLLayer copyCGLPixelFormatForDisplayMask:]): Deleted.
     71        (-[WebGLLayer copyCGLContextForPixelFormat:]): Deleted.
     72        (-[WebGLLayer drawInCGLContext:pixelFormat:forLayerTime:displayTime:]): Deleted.
     73
     74        * platform/graphics/mac/WebLayer.mm: Remove the definition of reloadValueForKeyPath.
     75
    1762017-10-05  Frederic Wang  <fwang@igalia.com>
    277
  • trunk/Source/WebCore/PAL/ChangeLog

    r222957 r222961  
     12017-10-05  Dean Jackson  <dino@apple.com>
     2
     3        Lots of missing frames in YouTube360 when fullscreen on MacBook
     4        https://bugs.webkit.org/show_bug.cgi?id=177903
     5        <rdar://problem/33273300>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Add reloadValueForKeyPath to replace setContentsChanged on CALayer.
     10
     11        * pal/spi/cocoa/QuartzCoreSPI.h:
     12
    1132017-10-05  Commit Queue  <commit-queue@webkit.org>
    214
  • trunk/Source/WebCore/PAL/pal/spi/cocoa/QuartzCoreSPI.h

    r222957 r222961  
    9292- (CGSize)size;
    9393- (void *)regionBeingDrawn;
    94 - (void)setContentsChanged;
     94- (void)reloadValueForKeyPath:(NSString *)keyPath;
    9595@property BOOL allowsGroupBlending;
    9696@property BOOL canDrawConcurrently;
  • trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h

    r222957 r222961  
    748748#if PLATFORM(COCOA)
    749749    PlatformGraphicsContext3D platformGraphicsContext3D() const { return m_contextObj; }
    750     Platform3DObject platformTexture() const { return m_fbo; }
     750    Platform3DObject platformTexture() const { return m_texture; }
    751751    CALayer* platformLayer() const { return reinterpret_cast<CALayer*>(m_webGLLayer.get()); }
    752752#else
     
    11481148    bool paintCompositedResultsToCanvas(ImageBuffer*);
    11491149
    1150 #if PLATFORM(IOS)
     1150#if PLATFORM(COCOA)
    11511151    void endPaint();
    11521152#endif
     1153
    11531154#if PLATFORM(MAC)
     1155    void allocateIOSurfaceBackingStore(IntSize);
     1156    void updateFramebufferTextureBackingStoreFromLayer();
    11541157    void updateCGLContext();
    11551158#endif
     1159
    11561160    void setContextVisibility(bool);
    11571161
  • trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm

    r222957 r222961  
    412412        [m_layer setContents:[caLayer contents]];
    413413    else
    414         [m_layer setContentsChanged];
     414        [m_layer reloadValueForKeyPath:@"contents"];
    415415    END_BLOCK_OBJC_EXCEPTIONS
    416416}
  • trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm

    r222957 r222961  
    480480#endif
    481481
     482    // Create the texture that will be used for the framebuffer.
    482483#if PLATFORM(IOS)
    483484    ::glGenRenderbuffers(1, &m_texture);
    484485#else
    485     // create a texture to render into
    486486    ::glGenTextures(1, &m_texture);
    487     ::glBindTexture(GL_TEXTURE_2D, m_texture);
    488     ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    489     ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    490     ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    491     ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    492     ::glBindTexture(GL_TEXTURE_2D, 0);
    493 #endif
    494 
    495     // create an FBO
     487    // We bind to GL_TEXTURE_RECTANGLE_EXT rather than TEXTURE_2D because
     488    // that's what is required for a texture backed by IOSurface.
     489    ::glBindTexture(GL_TEXTURE_RECTANGLE_EXT, m_texture);
     490    ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     491    ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     492    ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     493    ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     494    ::glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
     495#endif
     496
     497    // Create the framebuffer object.
    496498    ::glGenFramebuffersEXT(1, &m_fbo);
    497499    ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     
    501503        ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
    502504
    503     // create an multisample FBO
     505    // If necessary, create another framebuffer for the multisample results.
    504506    if (m_attrs.antialias) {
    505507        ::glGenFramebuffersEXT(1, &m_multisampleFBO);
     
    655657}
    656658
    657 #if PLATFORM(IOS)
    658659void GraphicsContext3D::endPaint()
    659660{
     
    661662    if (m_attrs.antialias)
    662663        resolveMultisamplingIfNecessary();
     664#if PLATFORM(IOS)
     665    // This is the place where we actually push our current rendering
     666    // results to the compositor on iOS. On macOS it comes from the
     667    // calling function, which is inside WebGLLayer.
    663668    ::glFlush();
    664669    ::glBindRenderbuffer(GL_RENDERBUFFER, m_texture);
    665670    [static_cast<EAGLContext*>(m_contextObj) presentRenderbuffer:GL_RENDERBUFFER];
    666671    [EAGLContext setCurrentContext:nil];
    667 }
    668 #endif
    669 
    670 #if PLATFORM(MAC)
     672#endif
     673}
     674
     675#if PLATFORM(MAC)
     676void GraphicsContext3D::allocateIOSurfaceBackingStore(IntSize size)
     677{
     678    LOG(WebGL, "GraphicsContext3D::allocateIOSurfaceBackingStore at %d x %d. (%p)", size.width(), size.height(), this);
     679    [m_webGLLayer allocateIOSurfaceBackingStoreWithSize:size usingAlpha:m_attrs.alpha];
     680}
     681
     682void GraphicsContext3D::updateFramebufferTextureBackingStoreFromLayer()
     683{
     684    LOG(WebGL, "GraphicsContext3D::updateFramebufferTextureBackingStoreFromLayer(). (%p)", this);
     685    [m_webGLLayer bindFramebufferToNextAvailableSurface];
     686}
     687
    671688void GraphicsContext3D::updateCGLContext()
    672689{
  • trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h

    r222957 r222961  
    2626#pragma once
    2727
     28#import "IOSurface.h"
     29#import "IntSize.h"
    2830#import <QuartzCore/QuartzCore.h>
    2931
     
    3335}
    3436
    35 #if PLATFORM(IOS)
     37#if PLATFORM(MAC)
     38@interface WebGLLayer : CALayer
     39#else
    3640@interface WebGLLayer : CAEAGLLayer
    37 #else
    38 @interface WebGLLayer : CAOpenGLLayer
    3941#endif
    4042{
    4143    WebCore::GraphicsContext3D* _context;
    4244    float _devicePixelRatio;
     45#if PLATFORM(MAC)
     46    std::unique_ptr<WebCore::IOSurface> _contentsBuffer;
     47    std::unique_ptr<WebCore::IOSurface> _drawingBuffer;
     48    std::unique_ptr<WebCore::IOSurface> _spareBuffer;
     49    WebCore::IntSize _bufferSize;
     50    BOOL _usingAlpha;
     51#endif
    4352}
    4453
     
    4958- (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
    5059
     60#if PLATFORM(MAC)
     61- (void)allocateIOSurfaceBackingStoreWithSize:(WebCore::IntSize)size usingAlpha:(BOOL)usingAlpha;
     62- (void)bindFramebufferToNextAvailableSurface;
     63#endif
     64
    5165@end
    5266
  • trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm

    r222957 r222961  
    3434#import "GraphicsLayerCA.h"
    3535#import "PlatformCALayer.h"
     36#import <pal/spi/cocoa/QuartzCoreSPI.h>
    3637#import <wtf/FastMalloc.h>
    3738#import <wtf/RetainPtr.h>
    3839
    39 #if !PLATFORM(IOS)
     40#if PLATFORM(MAC)
    4041#import <OpenGL/OpenGL.h>
    4142#import <OpenGL/gl.h>
     
    5455    _devicePixelRatio = context->getContextAttributes().devicePixelRatio;
    5556#if PLATFORM(MAC)
     57    if (!context->getContextAttributes().alpha)
     58        self.opaque = YES;
     59    self.transform = CATransform3DIdentity;
    5660    self.contentsScale = _devicePixelRatio;
    57     self.colorspace = sRGBColorSpaceRef();
    5861#endif
    5962    return self;
    6063}
    6164
    62 #if !PLATFORM(IOS)
    63 -(CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
     65#if PLATFORM(MAC)
     66// On Mac, we need to flip the layer to take into account
     67// that the IOSurface provides content in Y-up. This
     68// means that any incoming transform (unlikely, since this
     69// is a contents layer) and anchor point must add a
     70// Y scale of -1 and make sure the transform happens from
     71// the top.
     72
     73- (void)setTransform:(CATransform3D)t
    6474{
    65     // We're basically copying the pixel format object from the existing
    66     // WebGL context, so we don't need to use the display mask.
    67     UNUSED_PARAM(mask);
    68 
    69     CGLPixelFormatObj webglPixelFormat = CGLGetPixelFormat(_context->platformGraphicsContext3D());
    70 
    71     Vector<CGLPixelFormatAttribute> attribs;
    72     GLint value;
    73 
    74     CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAColorSize, &value);
    75     attribs.append(kCGLPFAColorSize);
    76     attribs.append(static_cast<CGLPixelFormatAttribute>(value));
    77 
    78     // We don't need to specify a depth size since we're only
    79     // using this context as a 2d blit destination for the WebGL FBO.
    80     attribs.append(kCGLPFADepthSize);
    81     attribs.append(static_cast<CGLPixelFormatAttribute>(0));
    82 
    83     CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAAllowOfflineRenderers, &value);
    84     if (value)
    85         attribs.append(kCGLPFAAllowOfflineRenderers);
    86 
    87     CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAAccelerated, &value);
    88     if (value)
    89         attribs.append(kCGLPFAAccelerated);
    90 
    91     CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAOpenGLProfile, &value);
    92     if (value) {
    93         attribs.append(kCGLPFAOpenGLProfile);
    94         attribs.append(static_cast<CGLPixelFormatAttribute>(value));
    95     }
    96 
    97     attribs.append(static_cast<CGLPixelFormatAttribute>(0));
    98 
    99     CGLPixelFormatObj pixelFormat;
    100     GLint numPixelFormats = 0;
    101     CGLChoosePixelFormat(attribs.data(), &pixelFormat, &numPixelFormats);
    102 
    103     ASSERT(pixelFormat);
    104     ASSERT(numPixelFormats);
    105 
    106     return pixelFormat;
     75    [super setTransform:CATransform3DScale(t, 1, -1, 1)];
    10776}
    10877
    109 -(CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
     78- (void)setAnchorPoint:(CGPoint)p
    11079{
    111     CGLContextObj contextObj;
    112     CGLCreateContext(pixelFormat, _context->platformGraphicsContext3D(), &contextObj);
    113     return contextObj;
    114 }
    115 
    116 -(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
    117 {
    118     if (!_context)
    119         return;
    120 
    121     _context->prepareTexture();
    122 
    123     CGLSetCurrentContext(glContext);
    124 
    125     CGRect frame = [self frame];
    126     frame.size.width *= _devicePixelRatio;
    127     frame.size.height *= _devicePixelRatio;
    128 
    129     // draw the FBO into the layer
    130     glViewport(0, 0, frame.size.width, frame.size.height);
    131     glMatrixMode(GL_PROJECTION);
    132     glLoadIdentity();
    133     glOrtho(-1, 1, -1, 1, -1, 1);
    134     glMatrixMode(GL_MODELVIEW);
    135     glLoadIdentity();
    136 
    137     glEnable(GL_TEXTURE_2D);
    138     glBindTexture(GL_TEXTURE_2D, _context->platformTexture());
    139 
    140     glBegin(GL_TRIANGLE_FAN);
    141         glTexCoord2f(0, 0);
    142         glVertex2f(-1, -1);
    143         glTexCoord2f(1, 0);
    144         glVertex2f(1, -1);
    145         glTexCoord2f(1, 1);
    146         glVertex2f(1, 1);
    147         glTexCoord2f(0, 1);
    148         glVertex2f(-1, 1);
    149     glEnd();
    150 
    151     glBindTexture(GL_TEXTURE_2D, 0);
    152     glDisable(GL_TEXTURE_2D);
    153 
    154     // Call super to finalize the drawing. By default all it does is call glFlush().
    155     [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
     80    [super setAnchorPoint:CGPointMake(p.x, 1.0 - p.y)];
    15681}
    15782
     
    204129        return;
    205130
    206 #if PLATFORM(IOS)
    207131    _context->endPaint();
    208 #else
    209     [super display];
     132
     133#if PLATFORM(MAC)
     134    _context->prepareTexture();
     135    if (_drawingBuffer) {
     136        std::swap(_contentsBuffer, _drawingBuffer);
     137        self.contents = _contentsBuffer->asLayerContents();
     138        [self reloadValueForKeyPath:@"contents"];
     139        [self bindFramebufferToNextAvailableSurface];
     140    }
    210141#endif
     142
    211143    _context->markLayerComposited();
    212144    PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
     
    215147}
    216148
     149#if PLATFORM(MAC)
     150- (void)allocateIOSurfaceBackingStoreWithSize:(IntSize)size usingAlpha:(BOOL)usingAlpha
     151{
     152    _bufferSize = size;
     153    _usingAlpha = usingAlpha;
     154    _contentsBuffer = WebCore::IOSurface::create(size, sRGBColorSpaceRef());
     155    _drawingBuffer = WebCore::IOSurface::create(size, sRGBColorSpaceRef());
     156    ASSERT(_contentsBuffer);
     157    ASSERT(_drawingBuffer);
     158}
     159
     160- (void)bindFramebufferToNextAvailableSurface
     161{
     162    GC3Denum texture = _context->platformTexture();
     163    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
     164
     165    if (_drawingBuffer && _drawingBuffer->isInUse()) {
     166        if (!_spareBuffer)
     167            _spareBuffer = WebCore::IOSurface::create(_bufferSize, sRGBColorSpaceRef());
     168        std::swap(_drawingBuffer, _spareBuffer);
     169    }
     170
     171    IOSurfaceRef ioSurface = _drawingBuffer->surface();
     172    GC3Denum internalFormat = _usingAlpha ? GL_RGBA : GL_RGB;
     173
     174    // Link the IOSurface to the texture.
     175    CGLError error = CGLTexImageIOSurface2D(_context->platformGraphicsContext3D(), GL_TEXTURE_RECTANGLE_ARB, internalFormat, _bufferSize.width(), _bufferSize.height(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ioSurface, 0);
     176    ASSERT_UNUSED(error, error == kCGLNoError);
     177}
     178#endif
     179
    217180@end
    218181
  • trunk/Source/WebCore/platform/graphics/mac/WebLayer.mm

    r222957 r222961  
    3131#import "PlatformCALayer.h"
    3232#import <QuartzCore/QuartzCore.h>
     33#import <pal/spi/cocoa/QuartzCoreSPI.h>
    3334#import <wtf/SetForScope.h>
    3435
     
    3839#import "WebCoreThread.h"
    3940#endif
    40 
    41 @interface CALayer(WebCoreCALayerPrivate)
    42 - (void)reloadValueForKeyPath:(NSString *)keyPath;
    43 @end
    4441
    4542using namespace WebCore;
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp

    r222957 r222961  
    3030
    3131#include "GraphicsContext3D.h"
     32
    3233#if PLATFORM(IOS)
    3334#include "GraphicsContext3DIOS.h"
    3435#endif
    35 
    3636#include "Extensions3DOpenGL.h"
    3737#include "IntRect.h"
     
    3939#include "NotImplemented.h"
    4040#include "TemporaryOpenGLSetting.h"
    41 
    4241#include <algorithm>
    4342#include <cstring>
     
    7170}
    7271
     72#if PLATFORM(MAC)
     73static void wipeAlphaChannelFromPixels(int width, int height, unsigned char* pixels)
     74{
     75    // We can assume this doesn't overflow because the calling functions
     76    // use checked arithmetic.
     77    int totalBytes = width * height * 4;
     78    for (int i = 0; i < totalBytes; i += 4)
     79        pixels[i + 3] = 255;
     80}
     81#endif
     82
    7383void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
    7484{
     
    99109    } else
    100110        ::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
     111
     112#if PLATFORM(MAC)
     113    if (!m_attrs.alpha)
     114        wipeAlphaChannelFromPixels(width, height, pixels);
     115#endif
    101116}
    102117
     
    171186    ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_texture);
    172187    setRenderbufferStorageFromDrawable(m_currentWidth, m_currentHeight);
     188#elif PLATFORM(MAC)
     189    allocateIOSurfaceBackingStore(IntSize(width, height));
     190    updateFramebufferTextureBackingStoreFromLayer();
     191    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_texture, 0);
    173192#else
    174193    ::glBindTexture(GL_TEXTURE_2D, m_texture);
     
    443462    if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)
    444463        ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
     464
     465#if PLATFORM(MAC)
     466    if (!m_attrs.alpha && (format == GraphicsContext3D::RGBA || format == GraphicsContext3D::BGRA) && (m_state.boundFBO == m_fbo || (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)))
     467        wipeAlphaChannelFromPixels(width, height, static_cast<unsigned char*>(data));
     468#endif
    445469}
    446470
Note: See TracChangeset for help on using the changeset viewer.