/* * Copyright (C) 2009-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "config.h" #if ENABLE(WEBGL) #import "GraphicsContextGLCocoa.h" // NOLINT #import "PlatformCALayer.h" #import "ProcessIdentity.h" #if PLATFORM(MAC) #import "DisplayConfigurationMonitor.h" #endif namespace WebCore { namespace { class DisplayBufferDisplayDelegate final : public GraphicsLayerContentsDisplayDelegate { public: static Ref create(bool isOpaque, float contentsScale) { return adoptRef(*new DisplayBufferDisplayDelegate(isOpaque, contentsScale)); } // GraphicsLayerContentsDisplayDelegate overrides. void prepareToDelegateDisplay(PlatformCALayer& layer) final { layer.setOpaque(m_isOpaque); layer.setContentsScale(m_contentsScale); } void display(PlatformCALayer& layer) final { if (m_displayBuffer) layer.setContents(*m_displayBuffer); else layer.clearContents(); } GraphicsLayer::CompositingCoordinatesOrientation orientation() const final { return GraphicsLayer::CompositingCoordinatesOrientation::BottomUp; } void setDisplayBuffer(IOSurface* displayBuffer) { if (!displayBuffer) { m_displayBuffer.reset(); return; } if (m_displayBuffer && displayBuffer->surface() == m_displayBuffer->surface()) return; m_displayBuffer = IOSurface::createFromSurface(displayBuffer->surface(), DestinationColorSpace::SRGB()); } private: DisplayBufferDisplayDelegate(bool isOpaque, float contentsScale) : m_contentsScale(contentsScale) , m_isOpaque(isOpaque) { } std::unique_ptr m_displayBuffer; const float m_contentsScale; const bool m_isOpaque; }; // GraphicsContextGL type that is used when WebGL is run in-process in WebContent process. class WebProcessGraphicsContextGLCocoa final : public GraphicsContextGLCocoa #if PLATFORM(MAC) , private DisplayConfigurationMonitor::Client #endif { public: ~WebProcessGraphicsContextGLCocoa(); // GraphicsContextGLCocoa overrides. RefPtr layerContentsDisplayDelegate() final { return m_layerContentsDisplayDelegate.ptr(); } void prepareForDisplay() final; private: #if PLATFORM(MAC) // DisplayConfigurationMonitor::Client overrides. void displayWasReconfigured() final; #endif WebProcessGraphicsContextGLCocoa(GraphicsContextGLAttributes&&); Ref m_layerContentsDisplayDelegate; friend RefPtr WebCore::createWebProcessGraphicsContextGL(const GraphicsContextGLAttributes&); friend class GraphicsContextGLOpenGL; }; WebProcessGraphicsContextGLCocoa::WebProcessGraphicsContextGLCocoa(GraphicsContextGLAttributes&& attributes) : GraphicsContextGLCocoa(WTFMove(attributes), { }) , m_layerContentsDisplayDelegate(DisplayBufferDisplayDelegate::create(!attributes.alpha, attributes.devicePixelRatio)) { #if PLATFORM(MAC) DisplayConfigurationMonitor::singleton().addClient(*this); #endif } WebProcessGraphicsContextGLCocoa::~WebProcessGraphicsContextGLCocoa() { #if PLATFORM(MAC) DisplayConfigurationMonitor::singleton().removeClient(*this); #endif } void WebProcessGraphicsContextGLCocoa::prepareForDisplay() { GraphicsContextGLCocoa::prepareForDisplay(); m_layerContentsDisplayDelegate->setDisplayBuffer(displayBuffer()); } #if PLATFORM(MAC) void WebProcessGraphicsContextGLCocoa::displayWasReconfigured() { updateContextOnDisplayReconfiguration(); } #endif } RefPtr createWebProcessGraphicsContextGL(const GraphicsContextGLAttributes& attributes) { auto context = adoptRef(new WebProcessGraphicsContextGLCocoa(GraphicsContextGLAttributes { attributes })); if (!context->initialize()) return nullptr; return context; } } #endif