blob: b99ab6e2b6398c89acf444988fd71a047a6dfe86 [file] [log] [blame]
/*
* 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<DisplayBufferDisplayDelegate> 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<IOSurface> 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<GraphicsLayerContentsDisplayDelegate> layerContentsDisplayDelegate() final { return m_layerContentsDisplayDelegate.ptr(); }
void prepareForDisplay() final;
private:
#if PLATFORM(MAC)
// DisplayConfigurationMonitor::Client overrides.
void displayWasReconfigured() final;
#endif
WebProcessGraphicsContextGLCocoa(GraphicsContextGLAttributes&&);
Ref<DisplayBufferDisplayDelegate> m_layerContentsDisplayDelegate;
friend RefPtr<GraphicsContextGL> 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<GraphicsContextGL> createWebProcessGraphicsContextGL(const GraphicsContextGLAttributes& attributes)
{
auto context = adoptRef(new WebProcessGraphicsContextGLCocoa(GraphicsContextGLAttributes { attributes }));
if (!context->initialize())
return nullptr;
return context;
}
}
#endif