Diff
Modified: branches/safari-604-branch/LayoutTests/TestExpectations (223254 => 223255)
--- branches/safari-604-branch/LayoutTests/TestExpectations 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/LayoutTests/TestExpectations 2017-10-12 21:15:32 UTC (rev 223255)
@@ -1401,4 +1401,6 @@
webkit.org/b/173333 imported/w3c/web-platform-tests/dom/nodes/Document-constructor-svg.svg [ Skip ]
+webkit.org/b/177997 webgl/1.0.2/conformance/textures/copy-tex-image-2d-formats.html [ Pass Failure ]
+
webkit.org/b/174284 media/video-source-before-src.html [ Skip ]
Modified: branches/safari-604-branch/Source/WebCore/ChangeLog (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/ChangeLog 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/ChangeLog 2017-10-12 21:15:32 UTC (rev 223255)
@@ -1,84 +1,82 @@
-2017-10-12 Dean Jackson <[email protected]>
+2017-10-13 Dean Jackson <[email protected]>
- [WebGL] VideoTextureCopierCV doesn't correctly restore vertex attribute state
- https://bugs.webkit.org/show_bug.cgi?id=176771
- <rdar://problem/34386621>
+ Cherry-pick r222961. rdar://problem/34891070
- Reviewed by Antoine Quint.
+ 2017-10-05 Dean Jackson <[email protected]>
- The OpenGL context in VideoTextureCopierCV wasn't being restored to
- the state it had before rendering a video to a texture. Specifically
- the vertex attribute values were never recorded by the state saver.
+ Lots of missing frames in YouTube360 when fullscreen on MacBook
+ https://bugs.webkit.org/show_bug.cgi?id=177903
+ <rdar://problem/33273300>
- Update the existing test of VideoTextureCopierCV so that it is
- explicitly doing something different from the WebCore code, which
- means that state will have to be correctly restored for the test
- to pass.
+ Reviewed by Sam Weinig.
- * platform/graphics/cv/VideoTextureCopierCV.cpp:
- (WebCore::VideoTextureCopierCV::copyVideoTextureToPlatformTexture): Make sure
- to record the vertex attribute state once we know the location of the position attribute.
- (WebCore::VideoTextureCopierCV::GC3DStateSaver::GC3DStateSaver):
- (WebCore::VideoTextureCopierCV::GC3DStateSaver::~GC3DStateSaver):
- (WebCore::VideoTextureCopierCV::GC3DStateSaver::saveVertexAttribState): Save all the
- applicable vertex attribute state information.
- * platform/graphics/cv/VideoTextureCopierCV.h: GC3DStateSaver can use a reference
- to the GC3D rather than a pointer.
+ 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.
-2017-10-12 Dean Jackson <[email protected]>
+ Covered by the existing WebGL tests.
- [WebGL] accelerated texImage2D for video doesn't respect flipY
- https://bugs.webkit.org/show_bug.cgi?id=176491
- <rdar://problem/33833511>
+ * 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.
- Reviewed by Jer Noble.
+ * 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.
- (Take 3 - this was rolled out due to a test failure)
+ * 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.
- Previously, if UNPACK_FLIP_Y_WEBGL was set to true, we'd either fall
- back to software or fail to upload texture data. Fix this by intercepting
- the texImage2D call, checking the orientation of the video, and running
- a small shader program to flip it if necessary.
+ * platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
+ (PlatformCALayerCocoa::copyContentsFromLayer): Replace the use of the
+ deprecated setContentsChanged with reloadValueForKeyPath.
- While there, implement UNPACK_PREMULTIPLY_ALPHA_WEBGL as well, although
- none of our media decoders support video with alpha, so unfortunately
- this will have no visible change.
+ * 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.
- Tests: fast/canvas/webgl/texImage2D-video-flipY-false.html
- fast/canvas/webgl/texImage2D-video-flipY-true.html
+ * 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/cocoa/CoreVideoSoftLink.cpp: Add link to CVOpenGL(ES)TextureGetCleanTexCoords,
- which is used to check the orientation of the source video.
- * platform/cocoa/CoreVideoSoftLink.h:
+ * platform/graphics/mac/WebLayer.mm: Remove the definition of reloadValueForKeyPath.
- * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
- (WebCore::MediaPlayerPrivateAVFoundationObjC::copyVideoTextureToPlatformTexture): We can
- now handle flipped or premultiplied requests.
- * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
- (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::copyVideoTextureToPlatformTexture): Ditto.
-
- * platform/graphics/cv/VideoTextureCopierCV.cpp:
- (WebCore::VideoTextureCopierCV::VideoTextureCopierCV): Rename readFramebuffer to
- simply framebuffer.
- (WebCore::VideoTextureCopierCV::~VideoTextureCopierCV): Delete the program and buffer
- if they were created.
- (WebCore::VideoTextureCopierCV::initializeContextObjects): Sets up the shader program
- and the vertex buffer for drawing. Also records the location of the uniforms.
- (WebCore::VideoTextureCopierCV::copyVideoTextureToPlatformTexture): Create a new
- framebuffer object, and render the video texture into that framebuffer using a
- shader that can flip the coordinates.
- (WebCore::VideoTextureCopierCV::GC3DStateSaver::GC3DStateSaver): Helper to restore
- the state of the user's GraphicsContext3D while we're intercepting calls.
- (WebCore::VideoTextureCopierCV::GC3DStateSaver::~GC3DStateSaver):
- * platform/graphics/cv/VideoTextureCopierCV.h:
-
- * platform/graphics/GraphicsContext3D.h: Add two new entry points, for direct shader
- compilation and attribute access. This avoids going through ANGLE.
- * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
- (WebCore::GraphicsContext3D::compileShader):
- (WebCore::GraphicsContext3D::compileShaderDirect):
- (WebCore::GraphicsContext3D::getAttribLocationDirect):
-
2017-10-11 Jason Marcell <[email protected]>
Cherry-pick r222963. rdar://problem/34891307
Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-10-12 21:15:32 UTC (rev 223255)
@@ -747,7 +747,7 @@
#if PLATFORM(COCOA)
PlatformGraphicsContext3D platformGraphicsContext3D() const { return m_contextObj; }
- Platform3DObject platformTexture() const { return m_fbo; }
+ Platform3DObject platformTexture() const { return m_texture; }
CALayer* platformLayer() const { return reinterpret_cast<CALayer*>(m_webGLLayer.get()); }
#else
PlatformGraphicsContext3D platformGraphicsContext3D();
@@ -1145,12 +1145,16 @@
RefPtr<ImageData> paintRenderingResultsToImageData();
bool paintCompositedResultsToCanvas(ImageBuffer*);
-#if PLATFORM(IOS)
+#if PLATFORM(COCOA)
void endPaint();
#endif
+
#if PLATFORM(MAC)
+ void allocateIOSurfaceBackingStore(IntSize);
+ void updateFramebufferTextureBackingStoreFromLayer();
void updateCGLContext();
#endif
+
void setContextVisibility(bool);
GraphicsContext3DPowerPreference powerPreferenceUsedForCreation() const { return m_powerPreferenceUsedForCreation; }
Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm 2017-10-12 21:15:32 UTC (rev 223255)
@@ -411,7 +411,7 @@
if ([m_layer contents] != [caLayer contents])
[m_layer setContents:[caLayer contents]];
else
- [m_layer setContentsChanged];
+ [m_layer reloadValueForKeyPath:@"contents"];
END_BLOCK_OBJC_EXCEPTIONS
}
Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm 2017-10-12 21:15:32 UTC (rev 223255)
@@ -479,20 +479,22 @@
::glEnable(GL_MULTISAMPLE);
#endif
+ // Create the texture that will be used for the framebuffer.
#if PLATFORM(IOS)
::glGenRenderbuffers(1, &m_texture);
#else
- // create a texture to render into
::glGenTextures(1, &m_texture);
- ::glBindTexture(GL_TEXTURE_2D, m_texture);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- ::glBindTexture(GL_TEXTURE_2D, 0);
+ // We bind to GL_TEXTURE_RECTANGLE_EXT rather than TEXTURE_2D because
+ // that's what is required for a texture backed by IOSurface.
+ ::glBindTexture(GL_TEXTURE_RECTANGLE_EXT, m_texture);
+ ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ ::glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ ::glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
#endif
- // create an FBO
+ // Create the framebuffer object.
::glGenFramebuffersEXT(1, &m_fbo);
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
@@ -500,7 +502,7 @@
if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
- // create an multisample FBO
+ // If necessary, create another framebuffer for the multisample results.
if (m_attrs.antialias) {
::glGenFramebuffersEXT(1, &m_multisampleFBO);
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
@@ -654,20 +656,35 @@
#endif
}
-#if PLATFORM(IOS)
void GraphicsContext3D::endPaint()
{
makeContextCurrent();
if (m_attrs.antialias)
resolveMultisamplingIfNecessary();
+#if PLATFORM(IOS)
+ // This is the place where we actually push our current rendering
+ // results to the compositor on iOS. On macOS it comes from the
+ // calling function, which is inside WebGLLayer.
::glFlush();
::glBindRenderbuffer(GL_RENDERBUFFER, m_texture);
[static_cast<EAGLContext*>(m_contextObj) presentRenderbuffer:GL_RENDERBUFFER];
[EAGLContext setCurrentContext:nil];
+#endif
}
-#endif
#if PLATFORM(MAC)
+void GraphicsContext3D::allocateIOSurfaceBackingStore(IntSize size)
+{
+ LOG(WebGL, "GraphicsContext3D::allocateIOSurfaceBackingStore at %d x %d. (%p)", size.width(), size.height(), this);
+ [m_webGLLayer allocateIOSurfaceBackingStoreWithSize:size usingAlpha:m_attrs.alpha];
+}
+
+void GraphicsContext3D::updateFramebufferTextureBackingStoreFromLayer()
+{
+ LOG(WebGL, "GraphicsContext3D::updateFramebufferTextureBackingStoreFromLayer(). (%p)", this);
+ [m_webGLLayer bindFramebufferToNextAvailableSurface];
+}
+
void GraphicsContext3D::updateCGLContext()
{
if (!m_contextObj)
Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h 2017-10-12 21:15:32 UTC (rev 223255)
@@ -25,6 +25,8 @@
#pragma once
+#import "IOSurface.h"
+#import "IntSize.h"
#import <QuartzCore/QuartzCore.h>
namespace WebCore {
@@ -32,14 +34,21 @@
class GraphicsContext3D;
}
-#if PLATFORM(IOS)
+#if PLATFORM(MAC)
+@interface WebGLLayer : CALayer
+#else
@interface WebGLLayer : CAEAGLLayer
-#else
-@interface WebGLLayer : CAOpenGLLayer
#endif
{
WebCore::GraphicsContext3D* _context;
float _devicePixelRatio;
+#if PLATFORM(MAC)
+ std::unique_ptr<WebCore::IOSurface> _contentsBuffer;
+ std::unique_ptr<WebCore::IOSurface> _drawingBuffer;
+ std::unique_ptr<WebCore::IOSurface> _spareBuffer;
+ WebCore::IntSize _bufferSize;
+ BOOL _usingAlpha;
+#endif
}
@property (nonatomic) WebCore::GraphicsContext3D* context;
@@ -48,5 +57,10 @@
- (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
+#if PLATFORM(MAC)
+- (void)allocateIOSurfaceBackingStoreWithSize:(WebCore::IntSize)size usingAlpha:(BOOL)usingAlpha;
+- (void)bindFramebufferToNextAvailableSurface;
+#endif
+
@end
Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm 2017-10-12 21:15:32 UTC (rev 223255)
@@ -33,10 +33,11 @@
#import "GraphicsLayer.h"
#import "GraphicsLayerCA.h"
#import "PlatformCALayer.h"
+#import "QuartzCoreSPI.h"
#import <wtf/FastMalloc.h>
#import <wtf/RetainPtr.h>
-#if !PLATFORM(IOS)
+#if PLATFORM(MAC)
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#endif
@@ -53,106 +54,30 @@
self = [super init];
_devicePixelRatio = context->getContextAttributes().devicePixelRatio;
#if PLATFORM(MAC)
+ if (!context->getContextAttributes().alpha)
+ self.opaque = YES;
+ self.transform = CATransform3DIdentity;
self.contentsScale = _devicePixelRatio;
- self.colorspace = sRGBColorSpaceRef();
#endif
return self;
}
-#if !PLATFORM(IOS)
--(CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
-{
- // We're basically copying the pixel format object from the existing
- // WebGL context, so we don't need to use the display mask.
- UNUSED_PARAM(mask);
+#if PLATFORM(MAC)
+// On Mac, we need to flip the layer to take into account
+// that the IOSurface provides content in Y-up. This
+// means that any incoming transform (unlikely, since this
+// is a contents layer) and anchor point must add a
+// Y scale of -1 and make sure the transform happens from
+// the top.
- CGLPixelFormatObj webglPixelFormat = CGLGetPixelFormat(_context->platformGraphicsContext3D());
-
- Vector<CGLPixelFormatAttribute> attribs;
- GLint value;
-
- CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAColorSize, &value);
- attribs.append(kCGLPFAColorSize);
- attribs.append(static_cast<CGLPixelFormatAttribute>(value));
-
- // We don't need to specify a depth size since we're only
- // using this context as a 2d blit destination for the WebGL FBO.
- attribs.append(kCGLPFADepthSize);
- attribs.append(static_cast<CGLPixelFormatAttribute>(0));
-
- CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAAllowOfflineRenderers, &value);
- if (value)
- attribs.append(kCGLPFAAllowOfflineRenderers);
-
- CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAAccelerated, &value);
- if (value)
- attribs.append(kCGLPFAAccelerated);
-
- CGLDescribePixelFormat(webglPixelFormat, 0, kCGLPFAOpenGLProfile, &value);
- if (value) {
- attribs.append(kCGLPFAOpenGLProfile);
- attribs.append(static_cast<CGLPixelFormatAttribute>(value));
- }
-
- attribs.append(static_cast<CGLPixelFormatAttribute>(0));
-
- CGLPixelFormatObj pixelFormat;
- GLint numPixelFormats = 0;
- CGLChoosePixelFormat(attribs.data(), &pixelFormat, &numPixelFormats);
-
- ASSERT(pixelFormat);
- ASSERT(numPixelFormats);
-
- return pixelFormat;
-}
-
--(CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
+- (void)setTransform:(CATransform3D)t
{
- CGLContextObj contextObj;
- CGLCreateContext(pixelFormat, _context->platformGraphicsContext3D(), &contextObj);
- return contextObj;
+ [super setTransform:CATransform3DScale(t, 1, -1, 1)];
}
--(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+- (void)setAnchorPoint:(CGPoint)p
{
- if (!_context)
- return;
-
- _context->prepareTexture();
-
- CGLSetCurrentContext(glContext);
-
- CGRect frame = [self frame];
- frame.size.width *= _devicePixelRatio;
- frame.size.height *= _devicePixelRatio;
-
- // draw the FBO into the layer
- glViewport(0, 0, frame.size.width, frame.size.height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-1, 1, -1, 1, -1, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, _context->platformTexture());
-
- glBegin(GL_TRIANGLE_FAN);
- glTexCoord2f(0, 0);
- glVertex2f(-1, -1);
- glTexCoord2f(1, 0);
- glVertex2f(1, -1);
- glTexCoord2f(1, 1);
- glVertex2f(1, 1);
- glTexCoord2f(0, 1);
- glVertex2f(-1, 1);
- glEnd();
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
-
- // Call super to finalize the drawing. By default all it does is call glFlush().
- [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
+ [super setAnchorPoint:CGPointMake(p.x, 1.0 - p.y)];
}
static void freeData(void *, const void *data, size_t /* size */)
@@ -203,11 +128,18 @@
if (!_context)
return;
-#if PLATFORM(IOS)
_context->endPaint();
-#else
- [super display];
+
+#if PLATFORM(MAC)
+ _context->prepareTexture();
+ if (_drawingBuffer) {
+ std::swap(_contentsBuffer, _drawingBuffer);
+ self.contents = _contentsBuffer->asLayerContents();
+ [self reloadValueForKeyPath:@"contents"];
+ [self bindFramebufferToNextAvailableSurface];
+ }
#endif
+
_context->markLayerComposited();
PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
if (layer && layer->owner())
@@ -214,6 +146,37 @@
layer->owner()->platformCALayerLayerDidDisplay(layer);
}
+#if PLATFORM(MAC)
+- (void)allocateIOSurfaceBackingStoreWithSize:(IntSize)size usingAlpha:(BOOL)usingAlpha
+{
+ _bufferSize = size;
+ _usingAlpha = usingAlpha;
+ _contentsBuffer = WebCore::IOSurface::create(size, sRGBColorSpaceRef());
+ _drawingBuffer = WebCore::IOSurface::create(size, sRGBColorSpaceRef());
+ ASSERT(_contentsBuffer);
+ ASSERT(_drawingBuffer);
+}
+
+- (void)bindFramebufferToNextAvailableSurface
+{
+ GC3Denum texture = _context->platformTexture();
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
+
+ if (_drawingBuffer && _drawingBuffer->isInUse()) {
+ if (!_spareBuffer)
+ _spareBuffer = WebCore::IOSurface::create(_bufferSize, sRGBColorSpaceRef());
+ std::swap(_drawingBuffer, _spareBuffer);
+ }
+
+ IOSurfaceRef ioSurface = _drawingBuffer->surface();
+ GC3Denum internalFormat = _usingAlpha ? GL_RGBA : GL_RGB;
+
+ // Link the IOSurface to the texture.
+ 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);
+ ASSERT_UNUSED(error, error == kCGLNoError);
+}
+#endif
+
@end
#endif // ENABLE(WEBGL)
Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/mac/WebLayer.mm (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/graphics/mac/WebLayer.mm 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/mac/WebLayer.mm 2017-10-12 21:15:32 UTC (rev 223255)
@@ -30,6 +30,7 @@
#import "GraphicsLayerCA.h"
#import "PlatformCALayer.h"
#import <QuartzCore/QuartzCore.h>
+#import "QuartzCoreSPI.h"
#import <wtf/SetForScope.h>
#if PLATFORM(IOS)
@@ -38,10 +39,6 @@
#import "WebCoreThread.h"
#endif
-@interface CALayer(WebCoreCALayerPrivate)
-- (void)reloadValueForKeyPath:(NSString *)keyPath;
-@end
-
using namespace WebCore;
#if PLATFORM(IOS)
Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp 2017-10-12 21:15:32 UTC (rev 223255)
@@ -29,16 +29,15 @@
#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "GraphicsContext3D.h"
+
#if PLATFORM(IOS)
#include "GraphicsContext3DIOS.h"
#endif
-
#include "Extensions3DOpenGL.h"
#include "IntRect.h"
#include "IntSize.h"
#include "NotImplemented.h"
#include "TemporaryOpenGLSetting.h"
-
#include <algorithm>
#include <cstring>
#include <wtf/MainThread.h>
@@ -70,6 +69,17 @@
notImplemented();
}
+#if PLATFORM(MAC)
+static void wipeAlphaChannelFromPixels(int width, int height, unsigned char* pixels)
+{
+ // We can assume this doesn't overflow because the calling functions
+ // use checked arithmetic.
+ int totalBytes = width * height * 4;
+ for (int i = 0; i < totalBytes; i += 4)
+ pixels[i + 3] = 255;
+}
+#endif
+
void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
{
// NVIDIA drivers have a bug where calling readPixels in BGRA can return the wrong values for the alpha channel when the alpha is off for the context.
@@ -98,6 +108,11 @@
#endif
} else
::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
+
+#if PLATFORM(MAC)
+ if (!m_attrs.alpha)
+ wipeAlphaChannelFromPixels(width, height, pixels);
+#endif
}
void GraphicsContext3D::validateAttributes()
@@ -170,6 +185,10 @@
::glBindRenderbuffer(GL_RENDERBUFFER, m_texture);
::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_texture);
setRenderbufferStorageFromDrawable(m_currentWidth, m_currentHeight);
+#elif PLATFORM(MAC)
+ allocateIOSurfaceBackingStore(IntSize(width, height));
+ updateFramebufferTextureBackingStoreFromLayer();
+ ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_texture, 0);
#else
::glBindTexture(GL_TEXTURE_2D, m_texture);
::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
@@ -442,6 +461,11 @@
::glReadPixels(x, y, width, height, format, type, data);
if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)
::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+
+#if PLATFORM(MAC)
+ if (!m_attrs.alpha && (format == GraphicsContext3D::RGBA || format == GraphicsContext3D::BGRA) && (m_state.boundFBO == m_fbo || (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO)))
+ wipeAlphaChannelFromPixels(width, height, static_cast<unsigned char*>(data));
+#endif
}
}
Modified: branches/safari-604-branch/Source/WebCore/platform/spi/cocoa/QuartzCoreSPI.h (223254 => 223255)
--- branches/safari-604-branch/Source/WebCore/platform/spi/cocoa/QuartzCoreSPI.h 2017-10-12 21:12:36 UTC (rev 223254)
+++ branches/safari-604-branch/Source/WebCore/platform/spi/cocoa/QuartzCoreSPI.h 2017-10-12 21:15:32 UTC (rev 223255)
@@ -77,7 +77,7 @@
- (CAContext *)context;
- (CGSize)size;
- (void *)regionBeingDrawn;
-- (void)setContentsChanged;
+- (void)reloadValueForKeyPath:(NSString *)keyPath;
@property BOOL allowsGroupBlending;
@property BOOL canDrawConcurrently;
@property BOOL contentsOpaque;