⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 268386 in webkit


Ignore:
Timestamp:
Oct 13, 2020, 12:16:57 AM (6 years ago)
Author:
commit-queue@webkit.org
Message:

Cocoa: Make WebGLLayer not dependent on GraphicsContextGLOpenGL
https://bugs.webkit.org/show_bug.cgi?id=217212
<rdar://problem/69876022>

Patch by Kimmo Kinnunen <kkinnunen@apple.com> on 2020-10-13
Reviewed by Dean Jackson.

Source/WebCore:

WebGLLayer was needlessly using GraphicsContextGLOpenGL.
This is problematic because WebGLLayer should work with
upcoming remote GraphicsContextGL implementation.

The prepare callgraph was:

GCGLOpenGL -> WebGLLayer -> GCGLOpenGL

Refactor it to be:

GCGLOpenGL -> WebGLLayer

Move the back buffer ownership to the GraphicsContextGLOpenGL.
Make the front buffer ownership explicit in WebGLLayer.
Move the EGL bindings ownerships of all buffers to
GraphicsContextGLOpenGL.

Make the WebGLLayer not use EGL or OpenGL, it does not
need and cannot use it as not all of its clients use OpenGL
(i.e. the above mentioned remote use-case).

Improves the memory usage by not allocating front buffers
unless needed. In case the canvas does not present, will
not allocate front buffers at all.

Improves error handling of the allocations and EGL bindings.

No new tests, a refactor.

  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/angle/GraphicsContextGLANGLE.cpp:

(WebCore::GraphicsContextGLOpenGL::reshapeFBOs):
(WebCore::GraphicsContextGLOpenGL::prepareTexture):
(WebCore::GraphicsContextGLOpenGL::prepareTextureImpl):

  • platform/graphics/angle/GraphicsContextGLANGLEUtilities.h: Added.

(WebCore::ScopedRestoreTextureBinding::ScopedRestoreTextureBinding):
(WebCore::ScopedRestoreTextureBinding::~ScopedRestoreTextureBinding):

  • platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:

(WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
(WebCore::GraphicsContextGLOpenGL::~GraphicsContextGLOpenGL):
(WebCore::GraphicsContextGLOpenGL::makeContextCurrent):
(WebCore::GraphicsContextGLOpenGL::reshapeDisplayBufferBacking):
(WebCore::GraphicsContextGLOpenGL::bindDisplayBufferBacking):
(WebCore::GraphicsContextGLOpenGL::prepareForDisplay):
(WebCore::GraphicsContextGLOpenGL::didDisplay):

  • platform/graphics/cocoa/WebGLLayer.h:
  • platform/graphics/cocoa/WebGLLayer.mm:

(-[WebGLLayer initWithClient:devicePixelRatio:]):
(-[WebGLLayer copyImageSnapshotWithColorSpace:]):
(-[WebGLLayer recycleBuffer]):
(-[WebGLLayer prepareForDisplayWithContents:]):
(-[WebGLLayer display]):
(-[WebGLLayer detachClient]):

  • platform/graphics/cocoa/WebGLLayerClient.h: Copied from Source/WebCore/platform/graphics/cocoa/WebGLLayer.h.

(WebCore::WebGLLayerClient::~WebGLLayerClient):

  • platform/graphics/opengl/GraphicsContextGLOpenGL.h:
  • platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp:

(WebCore::GraphicsContextGLOpenGL::reshapeFBOs):

Source/WebKit:

Removed unneeded inclusions of GraphicsContextGLOpenGL.h. The
file is now using non-public headers.

  • WebProcess/WebPage/WebPage.cpp:
  • WebProcess/WebPage/mac/WebPageMac.mm:
Location:
trunk/Source
Files:
1 added
11 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r268385 r268386  
     12020-10-13  Kimmo Kinnunen  <kkinnunen@apple.com>
     2
     3        Cocoa: Make WebGLLayer not dependent on  GraphicsContextGLOpenGL
     4        https://bugs.webkit.org/show_bug.cgi?id=217212
     5        <rdar://problem/69876022>
     6
     7        Reviewed by Dean Jackson.
     8
     9        WebGLLayer was needlessly using GraphicsContextGLOpenGL.
     10        This is problematic because WebGLLayer should work with
     11        upcoming remote GraphicsContextGL implementation.
     12
     13        The prepare callgraph was:
     14            GCGLOpenGL -> WebGLLayer -> GCGLOpenGL
     15        Refactor it to be:
     16            GCGLOpenGL -> WebGLLayer
     17
     18        Move the back buffer ownership to the GraphicsContextGLOpenGL.
     19        Make the front buffer ownership explicit in WebGLLayer.
     20        Move the EGL bindings ownerships of all buffers to
     21        GraphicsContextGLOpenGL.
     22
     23        Make the WebGLLayer not use EGL or OpenGL, it does not
     24        need and cannot use it as not all of its clients use OpenGL
     25        (i.e. the above mentioned remote use-case).
     26
     27        Improves the memory usage by not allocating front buffers
     28        unless needed. In case the canvas does not present, will
     29        not allocate front buffers at all.
     30
     31        Improves error handling of the allocations and EGL bindings.
     32
     33        No new tests, a refactor.
     34
     35        * WebCore.xcodeproj/project.pbxproj:
     36        * platform/graphics/angle/GraphicsContextGLANGLE.cpp:
     37        (WebCore::GraphicsContextGLOpenGL::reshapeFBOs):
     38        (WebCore::GraphicsContextGLOpenGL::prepareTexture):
     39        (WebCore::GraphicsContextGLOpenGL::prepareTextureImpl):
     40        * platform/graphics/angle/GraphicsContextGLANGLEUtilities.h: Added.
     41        (WebCore::ScopedRestoreTextureBinding::ScopedRestoreTextureBinding):
     42        (WebCore::ScopedRestoreTextureBinding::~ScopedRestoreTextureBinding):
     43        * platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:
     44        (WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
     45        (WebCore::GraphicsContextGLOpenGL::~GraphicsContextGLOpenGL):
     46        (WebCore::GraphicsContextGLOpenGL::makeContextCurrent):
     47        (WebCore::GraphicsContextGLOpenGL::reshapeDisplayBufferBacking):
     48        (WebCore::GraphicsContextGLOpenGL::bindDisplayBufferBacking):
     49        (WebCore::GraphicsContextGLOpenGL::prepareForDisplay):
     50        (WebCore::GraphicsContextGLOpenGL::didDisplay):
     51        * platform/graphics/cocoa/WebGLLayer.h:
     52        * platform/graphics/cocoa/WebGLLayer.mm:
     53        (-[WebGLLayer initWithClient:devicePixelRatio:]):
     54        (-[WebGLLayer copyImageSnapshotWithColorSpace:]):
     55        (-[WebGLLayer recycleBuffer]):
     56        (-[WebGLLayer prepareForDisplayWithContents:]):
     57        (-[WebGLLayer display]):
     58        (-[WebGLLayer detachClient]):
     59        * platform/graphics/cocoa/WebGLLayerClient.h: Copied from Source/WebCore/platform/graphics/cocoa/WebGLLayer.h.
     60        (WebCore::WebGLLayerClient::~WebGLLayerClient):
     61        * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
     62        * platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp:
     63        (WebCore::GraphicsContextGLOpenGL::reshapeFBOs):
     64
    1652020-10-12  Yusuke Suzuki  <ysuzuki@apple.com>
    266
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r268372 r268386  
    22172217                7AF9B20D18CFB5F400C64BEF /* JSVTTRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B20918CFB5F200C64BEF /* JSVTTRegion.h */; };
    22182218                7AF9B20F18CFB5F400C64BEF /* JSVTTRegionList.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B20B18CFB5F300C64BEF /* JSVTTRegionList.h */; };
     2219                7BB34A152534579100029D08 /* WebGLLayerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A132534579100029D08 /* WebGLLayerClient.h */; };
     2220                7BB34A1725345CB200029D08 /* GraphicsContextGLANGLEUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */; };
    22192221                7BE7427381FA906FBB4F0F2C /* JSSVGGraphicsElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 950C4C02BED8936F818E2F99 /* JSSVGGraphicsElement.h */; };
    22202222                7C029C6E2493C8F800268204 /* ColorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C029C6D2493C8F800268204 /* ColorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1006510067                7AF9B20A18CFB5F300C64BEF /* JSVTTRegionList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVTTRegionList.cpp; sourceTree = "<group>"; };
    1006610068                7AF9B20B18CFB5F300C64BEF /* JSVTTRegionList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVTTRegionList.h; sourceTree = "<group>"; };
     10069                7BB34A132534579100029D08 /* WebGLLayerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLLayerClient.h; sourceTree = "<group>"; };
     10070                7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsContextGLANGLEUtilities.h; sourceTree = "<group>"; };
    1006710071                7C011F3D24FAD360005BEF10 /* Settings.cpp.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = Settings.cpp.erb; sourceTree = "<group>"; };
    1006810072                7C011F3E24FAD360005BEF10 /* InternalSettingsGenerated.cpp.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = InternalSettingsGenerated.cpp.erb; sourceTree = "<group>"; };
     
    2187621880                                6E27F244229C9F8D00F1F632 /* ExtensionsGLANGLE.h */,
    2187721881                                6E27F2422298CE4B00F1F632 /* GraphicsContextGLANGLE.cpp */,
     21882                                7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */,
    2187821883                                6E290861229DB950000986E2 /* TemporaryANGLESetting.cpp */,
    2187921884                                6E290863229DB970000986E2 /* TemporaryANGLESetting.h */,
     
    2642726432                                49FFBF3D11C93EE3006A7118 /* WebGLLayer.h */,
    2642826433                                49FFBF3E11C93EE3006A7118 /* WebGLLayer.mm */,
     26434                                7BB34A132534579100029D08 /* WebGLLayerClient.h */,
    2642926435                                318436DB21B9DAA000ED383E /* WebGPULayer.h */,
    2643026436                                318436DD21B9DAA000ED383E /* WebGPULayer.mm */,
     
    3161031616                                934907E4125BBBC8007F23A0 /* GraphicsContextCG.h in Headers */,
    3161131617                                313DE87023A96973008FC47B /* GraphicsContextGL.h in Headers */,
     31618                                7BB34A1725345CB200029D08 /* GraphicsContextGLANGLEUtilities.h in Headers */,
    3161231619                                7C330A021DF8FAC600D3395C /* GraphicsContextGLAttributes.h in Headers */,
    3161331620                                49C7B9FC1042D3650009D447 /* GraphicsContextGLOpenGL.h in Headers */,
     
    3461034617                                49C7B9CF1042D32F0009D447 /* WebGLFramebuffer.h in Headers */,
    3461134618                                49FFBF3F11C93EE3006A7118 /* WebGLLayer.h in Headers */,
     34619                                7BB34A152534579100029D08 /* WebGLLayerClient.h in Headers */,
    3461234620                                93F1D5BB12D532C400832BEC /* WebGLLoseContext.h in Headers */,
    3461334621                                49C7B9D51042D32F0009D447 /* WebGLObject.h in Headers */,
  • trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp

    r268198 r268386  
    210210
    211211#if PLATFORM(COCOA)
    212     if (!allocateIOSurfaceBackingStore(size)) {
     212    if (!reshapeDisplayBufferBacking()) {
    213213        RELEASE_LOG(WebGL, "Fatal: Unable to allocate backing store of size %d x %d", width, height);
    214214        forceContextLost();
    215215        return true;
    216216    }
    217     updateFramebufferTextureBackingStoreFromLayer();
    218217    if (m_preserveDrawingBufferTexture) {
    219218        // The context requires the use of an intermediate texture in order to implement
     
    521520
    522521    makeContextCurrent();
     522    prepareTextureImpl();
     523}
     524
     525void GraphicsContextGLOpenGL::prepareTextureImpl()
     526{
     527    ASSERT(!m_layerComposited);
    523528
    524529    if (contextAttributes().antialias)
     
    556561            gl::BindFramebuffer(GL_FRAMEBUFFER, m_state.boundDrawFBO);
    557562    }
    558     gl::Flush();
    559563#endif
    560564}
  • trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm

    r268198 r268386  
    3030
    3131#import "ExtensionsGLANGLE.h"
     32#import "GraphicsContextGLANGLEUtilities.h"
    3233#import "GraphicsContextGLOpenGLManager.h"
    3334#import "HostWindow.h"
     
    4041#import <wtf/BlockObjCExceptions.h>
    4142#import <wtf/text/CString.h>
    42 
    43 #define EGL_EGL_PROTOTYPES 0
    44 // Skip the inclusion of ANGLE's explicit context entry points for now.
    45 #define GL_ANGLE_explicit_context
    46 #define GL_ANGLE_explicit_context_gles1
    47 typedef void* GLeglContext;
    48 #import <ANGLE/egl.h>
    49 #import <ANGLE/eglext.h>
    50 #import <ANGLE/eglext_angle.h>
    51 #import <ANGLE/entry_points_egl.h>
    52 #import <ANGLE/entry_points_egl_ext.h>
    53 #import <ANGLE/entry_points_gles_2_0_autogen.h>
    54 #import <ANGLE/entry_points_gles_ext_autogen.h>
    55 #import <ANGLE/gl2ext.h>
    56 #import <ANGLE/gl2ext_angle.h>
    5743
    5844#if PLATFORM(MAC)
     
    349335    // Create the WebGLLayer
    350336    BEGIN_BLOCK_OBJC_EXCEPTIONS
    351         m_webGLLayer = adoptNS([[WebGLLayer alloc] initWithGraphicsContextGL:this]);
     337        m_webGLLayer = adoptNS([[WebGLLayer alloc] initWithClient:this devicePixelRatio:attrs.devicePixelRatio]);
    352338#ifndef NDEBUG
    353339        [m_webGLLayer setName:@"WebGL Layer"];
    354340#endif
    355         [m_webGLLayer setEGLDisplay:m_displayObj config:m_configObj];
    356341    END_BLOCK_OBJC_EXCEPTIONS
    357342
     
    425410            gl::DeleteFramebuffers(1, &m_preserveDrawingBufferFBO);
    426411
    427         [m_webGLLayer releaseGLResources];
     412        if (m_displayBufferPbuffer) {
     413            EGL_ReleaseTexImage(m_displayObj, m_displayBufferPbuffer, EGL_BACK_BUFFER);
     414            EGL_DestroySurface(m_displayObj, m_displayBufferPbuffer);
     415        }
     416        auto recycledBuffer = [m_webGLLayer recycleBuffer];
     417        if (recycledBuffer.handle)
     418            EGL_DestroySurface(m_displayObj, recycledBuffer.handle);
     419        auto contentsHandle = [m_webGLLayer detachClient];
     420        if (contentsHandle)
     421            EGL_DestroySurface(m_displayObj, contentsHandle);
     422
    428423        EGL_MakeCurrent(m_displayObj, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    429424        EGL_DestroyContext(m_displayObj, m_contextObj);
    430         [m_webGLLayer setContext:nullptr];
    431425    }
    432426
     
    477471    if (!m_contextObj)
    478472        return false;
     473    // If there is no drawing buffer, we failed to allocate one during preparing for display.
     474    // The exception is the case when the context is used before reshaping.
     475    if (!m_displayBufferBacking && !getInternalFramebufferSize().isEmpty())
     476        return false;
    479477    // ANGLE has an early out for case where nothing changes. Calling MakeCurrent
    480478    // is important to set volatile platform context. See InitializeEGLDisplay().
     
    572570#endif
    573571
    574 bool GraphicsContextGLOpenGL::allocateIOSurfaceBackingStore(IntSize size)
    575 {
    576     LOG(WebGL, "GraphicsContextGLOpenGL::allocateIOSurfaceBackingStore at %d x %d. (%p)", size.width(), size.height(), this);
    577     return [m_webGLLayer allocateIOSurfaceBackingStoreWithSize:size usingAlpha:contextAttributes().alpha];
    578 }
    579 
    580 void GraphicsContextGLOpenGL::updateFramebufferTextureBackingStoreFromLayer()
    581 {
    582     LOG(WebGL, "GraphicsContextGLOpenGL::updateFramebufferTextureBackingStoreFromLayer(). (%p)", this);
    583     [m_webGLLayer bindFramebufferToNextAvailableSurface];
     572bool GraphicsContextGLOpenGL::reshapeDisplayBufferBacking()
     573{
     574    ASSERT(!getInternalFramebufferSize().isEmpty());
     575    // Reset the current backbuffer now before allocating a new one in order to slightly reduce memory pressure.
     576    if (m_displayBufferBacking) {
     577        m_displayBufferBacking.reset();
     578        EGL_ReleaseTexImage(m_displayObj, m_displayBufferPbuffer, EGL_BACK_BUFFER);
     579        EGL_DestroySurface(m_displayObj, m_displayBufferPbuffer);
     580        m_displayBufferPbuffer = EGL_NO_SURFACE;
     581    }
     582    // Reset the future recycled buffer now, because it most likely will not be reusable at the time it will be reused.
     583    auto recycledBuffer = [m_webGLLayer recycleBuffer];
     584    if (recycledBuffer.handle)
     585        EGL_DestroySurface(m_displayObj, recycledBuffer.handle);
     586    recycledBuffer.surface.reset();
     587
     588    auto backing = WebCore::IOSurface::create(getInternalFramebufferSize(), WebCore::sRGBColorSpaceRef());
     589    if (!backing)
     590        return false;
     591
     592    backing->migrateColorSpaceToProperties();
     593
     594    const bool usingAlpha = contextAttributes().alpha;
     595    const auto size = getInternalFramebufferSize();
     596    const EGLint surfaceAttributes[] = {
     597        EGL_WIDTH, size.width(),
     598        EGL_HEIGHT, size.height(),
     599        EGL_IOSURFACE_PLANE_ANGLE, 0,
     600        EGL_TEXTURE_TARGET, WebCore::GraphicsContextGLOpenGL::EGLIOSurfaceTextureTarget(),
     601        EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, usingAlpha ? GL_BGRA_EXT : GL_RGB,
     602        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
     603        EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
     604        // Only has an effect on the iOS Simulator.
     605        EGL_IOSURFACE_USAGE_HINT_ANGLE, EGL_IOSURFACE_WRITE_HINT_ANGLE,
     606        EGL_NONE, EGL_NONE
     607    };
     608    EGLSurface pbuffer = EGL_CreatePbufferFromClientBuffer(m_displayObj, EGL_IOSURFACE_ANGLE, backing->surface(), m_configObj, surfaceAttributes);
     609    if (!pbuffer)
     610        return false;
     611    return bindDisplayBufferBacking(WTFMove(backing), pbuffer);
     612}
     613
     614bool GraphicsContextGLOpenGL::bindDisplayBufferBacking(std::unique_ptr<IOSurface> backing, void* pbuffer)
     615{
     616    GCGLenum textureTarget = IOSurfaceTextureTarget();
     617    ScopedRestoreTextureBinding restoreBinding(IOSurfaceTextureTargetQuery(), textureTarget, textureTarget != TEXTURE_RECTANGLE_ARB);
     618    gl::BindTexture(textureTarget, m_texture);
     619    if (!EGL_BindTexImage(m_displayObj, pbuffer, EGL_BACK_BUFFER)) {
     620        EGL_DestroySurface(m_displayObj, pbuffer);
     621        return false;
     622    }
     623    m_displayBufferPbuffer = pbuffer;
     624    m_displayBufferBacking = WTFMove(backing);
     625    return true;
    584626}
    585627
     
    638680void GraphicsContextGLOpenGL::prepareForDisplay()
    639681{
    640     [m_webGLLayer prepareForDisplay];
     682    if (m_layerComposited)
     683        return;
     684    if (!makeContextCurrent())
     685        return;
     686    prepareTextureImpl();
     687
     688    // The IOSurface will be used from other graphics subsystem, so flush GL commands.
     689    gl::Flush();
     690
     691    auto recycledBuffer = [m_webGLLayer recycleBuffer];
     692
     693    EGL_ReleaseTexImage(m_displayObj, m_displayBufferPbuffer, EGL_BACK_BUFFER);
     694    [m_webGLLayer prepareForDisplayWithContents: {WTFMove(m_displayBufferBacking), m_displayBufferPbuffer}];
     695    m_displayBufferPbuffer = EGL_NO_SURFACE;
     696
     697    if (recycledBuffer.surface && recycledBuffer.surface->size() == getInternalFramebufferSize()) {
     698        if (bindDisplayBufferBacking(WTFMove(recycledBuffer.surface), recycledBuffer.handle))
     699            return;
     700    }
     701    recycledBuffer.surface.reset();
     702    if (recycledBuffer.handle)
     703        EGL_DestroySurface(m_displayObj, recycledBuffer.handle);
     704    // Error will be handled by next call to makeContextCurrent() which will notice lack of display buffer.
     705    reshapeDisplayBufferBacking();
     706}
     707
     708void GraphicsContextGLOpenGL::didDisplay()
     709{
     710    markLayerComposited();
    641711}
    642712
  • trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h

    r268198 r268386  
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
    2626#import "IOSurface.h"
    27 #import "IntSize.h"
    2827#import <QuartzCore/QuartzCore.h>
    2928#import <wtf/NakedPtr.h>
    3029
    3130namespace WebCore {
    32 class GraphicsLayer;
    33 class GraphicsContextGLOpenGL;
     31class WebGLLayerClient;
     32struct WebGLLayerBuffer {
     33    std::unique_ptr<WebCore::IOSurface> surface; // The actual contents.
     34    void* handle { nullptr }; // Client specific metadata handle (such as EGLSurface).
     35};
    3436}
    3537
    3638ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    3739
     40// A layer class implementing front buffer management of a 3-buffering swap
     41// chain of IOSurfaces.
     42// The layer will own the IOSurfaces it uses for display.
     43// The client may attach metadata to each IOSurface and will receive the metadata
     44// back once the IOSurface has been displayed. However, the client may not neccessarily
     45// be able to obtain the IOSurface itself for reuse.
     46// Example use of the metadata is to use EGLSurface binding as the metadata. This way
     47// when the WebGLLayer is done with the IOSurface display, the client can continue using
     48// the existing binding obtained through the buffer recycle logic.
    3849@interface WebGLLayer : CALayer
    3950
    40 @property (nonatomic) NakedPtr<WebCore::GraphicsContextGLOpenGL> context;
    41 
    42 - (id)initWithGraphicsContextGL:(NakedPtr<WebCore::GraphicsContextGLOpenGL>)context;
     51- (id)initWithClient:(NakedPtr<WebCore::WebGLLayerClient>)client devicePixelRatio:(float)devicePixelRatio;
    4352
    4453- (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
    4554
    46 - (void)prepareForDisplay;
     55// Returns the metadata handle of last unused contents buffer.
     56// Client may recieve back also the ownership of the contents surface, in case it is available at the
     57// time of the call.
     58// Returns either:
     59// - Empty buffer if no buffer has been submitted.
     60// - Buffer with empty surface and non-empty metadata handle if the recycled buffer was available
     61//   but the surface is still in use.
     62// - Surface and handle.
     63- (WebCore::WebGLLayerBuffer)recycleBuffer;
    4764
    48 - (bool)allocateIOSurfaceBackingStoreWithSize:(WebCore::IntSize)size usingAlpha:(BOOL)usingAlpha;
    49 - (void)bindFramebufferToNextAvailableSurface;
    50 - (void)setEGLDisplay:(void*)eglDisplay config:(void*)eglConfig;
    51 - (void)releaseGLResources;
     65// Prepares the layer for display with a contents buffer.
     66// Client transfers the ownership of the IOSurface surface in the `buffer`.
     67- (void)prepareForDisplayWithContents:(WebCore::WebGLLayerBuffer)buffer;
     68
     69// Detaches the client and returns the current contents buffer metadata handle.
     70// The if multiple buffers have been submitted, recycleBuffer must have been called before calling
     71// this.
     72// The client will not receive `WebGLLayerClient` notifications after calling this.
     73- (void*)detachClient;
    5274
    5375@end
  • trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm

    r268198 r268386  
    2929#import "WebGLLayer.h"
    3030
    31 #import "GraphicsContextCG.h"
    32 #import "GraphicsContextGLOpenGL.h"
    3331#import "GraphicsLayer.h"
    3432#import "GraphicsLayerCA.h"
    35 #import "ImageBufferUtilitiesCG.h"
    36 #import "NotImplemented.h"
    3733#import "PlatformCALayer.h"
     34#import "WebGLLayerClient.h"
    3835#import <pal/spi/cocoa/QuartzCoreSPI.h>
    39 #import <wtf/FastMalloc.h>
    4036#import <wtf/RetainPtr.h>
    4137
    42 #define EGL_EGL_PROTOTYPES 0
    43 #import <ANGLE/egl.h>
    44 #import <ANGLE/eglext.h>
    45 #import <ANGLE/eglext_angle.h>
    46 #import <ANGLE/entry_points_egl.h>
    47 #import <ANGLE/entry_points_gles_2_0_autogen.h>
    48 // Skip the inclusion of ANGLE's explicit context entry points for now.
    49 #define GL_ANGLE_explicit_context
    50 #import <ANGLE/gl2ext.h>
    51 #import <ANGLE/gl2ext_angle.h>
     38@implementation WebGLLayer {
     39    NakedPtr<WebCore::WebGLLayerClient> _client;
     40    WebCore::WebGLLayerBuffer _contentsBuffer;
     41    WebCore::WebGLLayerBuffer _spareBuffer;
    5242
    53 namespace {
    54     class ScopedRestoreTextureBinding {
    55         WTF_MAKE_NONCOPYABLE(ScopedRestoreTextureBinding);
    56     public:
    57         ScopedRestoreTextureBinding(GLenum bindingPointQuery, GLenum bindingPoint)
    58             : m_bindingPoint(bindingPoint)
    59         {
    60             gl::GetIntegerv(bindingPointQuery, &m_bindingValue);
    61         }
    62 
    63         ~ScopedRestoreTextureBinding()
    64         {
    65             gl::BindTexture(m_bindingPoint, m_bindingValue);
    66         }
    67 
    68     private:
    69         GLint m_bindingPoint { 0 };
    70         GLint m_bindingValue { 0 };
    71     };
    72 }
    73 
    74 @implementation WebGLLayer {
    75     float _devicePixelRatio;
    76     std::unique_ptr<WebCore::IOSurface> _contentsBuffer;
    77     std::unique_ptr<WebCore::IOSurface> _drawingBuffer;
    78     std::unique_ptr<WebCore::IOSurface> _spareBuffer;
    79     WebCore::IntSize _bufferSize;
    80     BOOL _usingAlpha;
    81     void* _eglDisplay;
    82     void* _eglConfig;
    83     void* _contentsPbuffer;
    84     void* _drawingPbuffer;
    85     void* _sparePbuffer;
    86     void* _latchedPbuffer;
    8743    BOOL _preparedForDisplay;
    8844}
    8945
    90 - (id)initWithGraphicsContextGL:(NakedPtr<WebCore::GraphicsContextGLOpenGL>)context
     46- (id)initWithClient:(NakedPtr<WebCore::WebGLLayerClient>)client devicePixelRatio:(float)devicePixelRatio
    9147{
    92     _context = context;
     48    _client = client;
    9349    self = [super init];
    94     auto attributes = context->contextAttributes();
    95     _devicePixelRatio = attributes.devicePixelRatio;
    96     self.contentsOpaque = !attributes.alpha;
    9750    self.transform = CATransform3DIdentity;
    98     self.contentsScale = _devicePixelRatio;
     51    self.contentsScale = devicePixelRatio;
    9952    return self;
    10053}
     
    11871- (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace
    11972{
    120     if (!_context)
    121         return nullptr;
    12273    // FIXME: implement. https://bugs.webkit.org/show_bug.cgi?id=217377
     74    // When implementing, remember to use self.contentsScale.
    12375    UNUSED_PARAM(colorSpace);
    12476    return nullptr;
    12577}
    12678
    127 - (void)prepareForDisplay
     79- (WebCore::WebGLLayerBuffer) recycleBuffer
    12880{
    129     if (!_context)
    130         return;
     81    if (_spareBuffer.surface) {
     82        if (_spareBuffer.surface->isInUse())
     83            _spareBuffer.surface.reset();
     84        return WTFMove(_spareBuffer);
     85    }
     86    return { };
     87}
    13188
    132     // To avoid running any OpenGL code in `display`, this method should be called
    133     // at the end of the rendering task. We will flush all painting commands
    134     // leaving the buffers ready to composite.
    135 
    136     if (!_context->makeContextCurrent()) {
    137         // Context is likely being torn down.
    138         return;
    139     }
    140     _context->prepareTexture();
    141     if (_drawingBuffer) {
    142         if (_latchedPbuffer) {
    143             WTF::Optional<ScopedRestoreTextureBinding> restoreBinding;
    144             GCGLenum textureTarget = WebCore::GraphicsContextGLOpenGL::IOSurfaceTextureTarget();
    145             // We don't need to restore GL_TEXTURE_RECTANGLE because it's not accessible from user code.
    146             if (textureTarget != WebCore::GraphicsContextGL::TEXTURE_RECTANGLE_ARB)
    147                 restoreBinding.emplace(WebCore::GraphicsContextGLOpenGL::IOSurfaceTextureTargetQuery(), textureTarget);
    148             GCGLenum texture = _context->platformTexture();
    149             gl::BindTexture(textureTarget, texture);
    150             if (!EGL_ReleaseTexImage(_eglDisplay, _latchedPbuffer, EGL_BACK_BUFFER)) {
    151                 // FIXME: report error.
    152                 notImplemented();
    153             }
    154             _latchedPbuffer = nullptr;
    155         }
    156 
    157         std::swap(_contentsBuffer, _drawingBuffer);
    158         std::swap(_contentsPbuffer, _drawingPbuffer);
    159         [self bindFramebufferToNextAvailableSurface];
    160     }
     89- (void)prepareForDisplayWithContents:(WebCore::WebGLLayerBuffer) buffer
     90{
     91    ASSERT(!_spareBuffer.surface);
     92    _spareBuffer = WTFMove(_contentsBuffer);
     93    _contentsBuffer = WTFMove(buffer);
    16194    [self setNeedsDisplay];
    16295    _preparedForDisplay = YES;
     
    16598- (void)display
    16699{
    167     if (!_context)
    168         return;
    169 
    170     // At this point we've painted into the _drawingBuffer and swapped it with the old _contentsBuffer,
    171     // so all we need to do here is tickle the CALayer to let it know it has new contents.
    172     // This avoids running any OpenGL code in this method.
    173 
    174     if (_contentsBuffer && _preparedForDisplay) {
    175         self.contents = _contentsBuffer->asLayerContents();
     100    if (_contentsBuffer.surface && _preparedForDisplay) {
     101        self.contents = _contentsBuffer.surface->asLayerContents();
    176102        [self reloadValueForKeyPath:@"contents"];
    177103    }
    178 
    179     _context->markLayerComposited();
     104    if (_client)
     105        _client->didDisplay();
    180106    auto layer = WebCore::PlatformCALayer::platformCALayerForLayer((__bridge void*)self);
    181107    if (layer && layer->owner())
     
    185111}
    186112
    187 - (void)setEGLDisplay:(void*)display config:(void*)config
     113- (void*) detachClient
    188114{
    189     _eglDisplay = display;
    190     _eglConfig = config;
     115    ASSERT(!_spareBuffer.surface);
     116    _client = nil;
     117    void* result = _contentsBuffer.handle;
     118    _contentsBuffer.handle = nullptr;
     119    return result;
    191120}
    192 
    193 - (void)releaseGLResources
    194 {
    195     if (!_context)
    196         return;
    197 
    198     if (_context->makeContextCurrent() && _latchedPbuffer) {
    199         EGL_ReleaseTexImage(_eglDisplay, _latchedPbuffer, EGL_BACK_BUFFER);
    200         _latchedPbuffer = nullptr;
    201     }
    202 
    203     EGL_DestroySurface(_eglDisplay, _contentsPbuffer);
    204     EGL_DestroySurface(_eglDisplay, _drawingPbuffer);
    205     EGL_DestroySurface(_eglDisplay, _sparePbuffer);
    206 }
    207 
    208 - (bool)allocateIOSurfaceBackingStoreWithSize:(WebCore::IntSize)size usingAlpha:(BOOL)usingAlpha
    209 {
    210     _bufferSize = size;
    211     _usingAlpha = usingAlpha;
    212     _contentsBuffer = WebCore::IOSurface::create(size, WebCore::sRGBColorSpaceRef());
    213     _drawingBuffer = WebCore::IOSurface::create(size, WebCore::sRGBColorSpaceRef());
    214     _spareBuffer = WebCore::IOSurface::create(size, WebCore::sRGBColorSpaceRef());
    215 
    216     if (!_contentsBuffer || !_drawingBuffer || !_spareBuffer)
    217         return false;
    218 
    219     _contentsBuffer->migrateColorSpaceToProperties();
    220     _drawingBuffer->migrateColorSpaceToProperties();
    221     _spareBuffer->migrateColorSpaceToProperties();
    222     const EGLint surfaceAttributes[] = {
    223         EGL_WIDTH, size.width(),
    224         EGL_HEIGHT, size.height(),
    225         EGL_IOSURFACE_PLANE_ANGLE, 0,
    226         EGL_TEXTURE_TARGET, WebCore::GraphicsContextGLOpenGL::EGLIOSurfaceTextureTarget(),
    227         EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, usingAlpha ? GL_BGRA_EXT : GL_RGB,
    228         EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
    229         EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,
    230         // Only has an effect on the iOS Simulator.
    231         EGL_IOSURFACE_USAGE_HINT_ANGLE, EGL_IOSURFACE_WRITE_HINT_ANGLE,
    232         EGL_NONE, EGL_NONE
    233     };
    234 
    235     _contentsPbuffer = EGL_CreatePbufferFromClientBuffer(_eglDisplay, EGL_IOSURFACE_ANGLE, _contentsBuffer->surface(), _eglConfig, surfaceAttributes);
    236     _drawingPbuffer = EGL_CreatePbufferFromClientBuffer(_eglDisplay, EGL_IOSURFACE_ANGLE, _drawingBuffer->surface(), _eglConfig, surfaceAttributes);
    237     _sparePbuffer = EGL_CreatePbufferFromClientBuffer(_eglDisplay, EGL_IOSURFACE_ANGLE, _spareBuffer->surface(), _eglConfig, surfaceAttributes);
    238 
    239     if (!_contentsPbuffer || !_drawingPbuffer || !_sparePbuffer)
    240         return false;
    241 
    242     return true;
    243 }
    244 
    245 - (void)bindFramebufferToNextAvailableSurface
    246 {
    247     WTF::Optional<ScopedRestoreTextureBinding> restoreBinding;
    248     GCGLenum textureTarget = WebCore::GraphicsContextGLOpenGL::IOSurfaceTextureTarget();
    249     // We don't need to restore GL_TEXTURE_RECTANGLE because it's not accessible from user code.
    250     if (textureTarget != WebCore::GraphicsContextGL::TEXTURE_RECTANGLE_ARB)
    251         restoreBinding.emplace(WebCore::GraphicsContextGLOpenGL::IOSurfaceTextureTargetQuery(), textureTarget);
    252 
    253     GCGLenum texture = _context->platformTexture();
    254     gl::BindTexture(textureTarget, texture);
    255 
    256     if (_latchedPbuffer) {
    257         if (!EGL_ReleaseTexImage(_eglDisplay, _latchedPbuffer, EGL_BACK_BUFFER)) {
    258             // FIXME: report error.
    259             notImplemented();
    260         }
    261         _latchedPbuffer = nullptr;
    262     }
    263 
    264     if (_drawingBuffer && _drawingBuffer->isInUse()) {
    265         std::swap(_drawingBuffer, _spareBuffer);
    266         std::swap(_drawingPbuffer, _sparePbuffer);
    267     }
    268 
    269     // Link the IOSurface to the texture via the previously-created pbuffer.
    270     if (!EGL_BindTexImage(_eglDisplay, _drawingPbuffer, EGL_BACK_BUFFER)) {
    271         // FIXME: report error.
    272         notImplemented();
    273     }
    274     _latchedPbuffer = _drawingPbuffer;
    275 }
    276 
    277121@end
    278122
  • trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayerClient.h

    r268385 r268386  
    11/*
    2  * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
    26 #import "IOSurface.h"
    27 #import "IntSize.h"
    28 #import <QuartzCore/QuartzCore.h>
    29 #import <wtf/NakedPtr.h>
     26#pragma once
    3027
    3128namespace WebCore {
    32 class GraphicsLayer;
    33 class GraphicsContextGLOpenGL;
     29
     30class WebGLLayerClient {
     31public:
     32    virtual ~WebGLLayerClient() { }
     33    virtual void didDisplay() = 0;
     34};
     35
    3436}
    35 
    36 ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    37 
    38 @interface WebGLLayer : CALayer
    39 
    40 @property (nonatomic) NakedPtr<WebCore::GraphicsContextGLOpenGL> context;
    41 
    42 - (id)initWithGraphicsContextGL:(NakedPtr<WebCore::GraphicsContextGLOpenGL>)context;
    43 
    44 - (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
    45 
    46 - (void)prepareForDisplay;
    47 
    48 - (bool)allocateIOSurfaceBackingStoreWithSize:(WebCore::IntSize)size usingAlpha:(BOOL)usingAlpha;
    49 - (void)bindFramebufferToNextAvailableSurface;
    50 - (void)setEGLDisplay:(void*)eglDisplay config:(void*)eglConfig;
    51 - (void)releaseGLResources;
    52 
    53 @end
    54 
    55 ALLOW_DEPRECATED_DECLARATIONS_END
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h

    r268198 r268386  
    3636#include <wtf/UniqueArray.h>
    3737
     38#if PLATFORM(COCOA)
     39#include "IOSurface.h"
     40#include "WebGLLayerClient.h"
     41#endif
     42
    3843#if USE(CA)
    3944#include "PlatformCALayer.h"
     
    5560OBJC_CLASS CALayer;
    5661OBJC_CLASS WebGLLayer;
    57 typedef struct __IOSurface* IOSurfaceRef;
    5862#endif // PLATFORM(COCOA)
    5963
     
    8488class GraphicsContextGLOpenGLPrivate;
    8589
    86 class GraphicsContextGLOpenGL : public GraphicsContextGL {
     90class GraphicsContextGLOpenGL : public GraphicsContextGL
     91#if PLATFORM(COCOA)
     92    , private WebGLLayerClient
     93#endif
     94{
    8795public:
    8896    class Client {
     
    544552
    545553#if PLATFORM(COCOA)
    546     bool allocateIOSurfaceBackingStore(IntSize);
    547     void updateFramebufferTextureBackingStoreFromLayer();
     554    bool reshapeDisplayBufferBacking();
     555    bool bindDisplayBufferBacking(std::unique_ptr<IOSurface> backing, void* pbuffer);
    548556#if PLATFORM(MAC)
    549557    void updateCGLContext();
     
    682690
    683691    bool reshapeFBOs(const IntSize&);
     692    void prepareTextureImpl();
    684693    void resolveMultisamplingIfNecessary(const IntRect& = IntRect());
    685694    void attachDepthAndStencilBufferIfNeeded(GCGLuint internalDepthStencilFormat, int width, int height);
     
    687696#if PLATFORM(COCOA)
    688697    bool allowOfflineRenderers() const;
     698    // WebGLLayerClient overrides.
     699    void didDisplay() override;
    689700#endif
    690701
     
    891902
    892903#if PLATFORM(COCOA)
     904    // Backing store for the the buffer which is eventually used for display.
     905    // When preserveDrawingBuffer == false, this is the drawing buffer backing store.
     906    // When preserveDrawingBuffer == true, this is blitted to during display prepare.
     907    std::unique_ptr<IOSurface> m_displayBufferBacking;
     908    void* m_displayBufferPbuffer { nullptr };
     909
    893910    bool m_hasSwitchedToHighPerformanceGPU { false };
    894911#endif
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp

    r268198 r268386  
    165165        return true;
    166166    }
    167     updateFramebufferTextureBackingStoreFromLayer();
    168167    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_texture, 0);
    169168#endif // !USE(OPENGL_ES))
  • trunk/Source/WebKit/ChangeLog

    r268384 r268386  
     12020-10-13  Kimmo Kinnunen  <kkinnunen@apple.com>
     2
     3        Cocoa: Make WebGLLayer not dependent on  GraphicsContextGLOpenGL
     4        https://bugs.webkit.org/show_bug.cgi?id=217212
     5        <rdar://problem/69876022>
     6
     7        Reviewed by Dean Jackson.
     8
     9        Removed unneeded inclusions of GraphicsContextGLOpenGL.h. The
     10        file is now using non-public headers.
     11
     12        * WebProcess/WebPage/WebPage.cpp:
     13        * WebProcess/WebPage/mac/WebPageMac.mm:
     14
    1152020-10-12  Devin Rousso  <drousso@apple.com>
    216
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r268313 r268386  
    176176#include <WebCore/FrameView.h>
    177177#include <WebCore/FullscreenManager.h>
    178 #include <WebCore/GraphicsContextGLOpenGL.h>
    179178#include <WebCore/HTMLAttachmentElement.h>
    180179#include <WebCore/HTMLFormElement.h>
  • trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm

    r268116 r268386  
    7272#import <WebCore/FrameView.h>
    7373#import <WebCore/GraphicsContext.h>
    74 #import <WebCore/GraphicsContextGLOpenGL.h>
    7574#import <WebCore/HTMLConverter.h>
    7675#import <WebCore/HTMLPlugInImageElement.h>
Note: See TracChangeset for help on using the changeset viewer.