[WebGL] Add a pure virtual base class for GraphicsContext3D
[WebKit-https.git] / Source / WebCore / platform / graphics / nicosia / texmap / NicosiaGC3DLayer.cpp
1 /*
2  * Copyright (C) 2018 Metrological Group B.V.
3  * Copyright (C) 2018 Igalia S.L.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above
12  *    copyright notice, this list of conditions and the following
13  *    disclaimer in the documentation and/or other materials provided
14  *    with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "NicosiaGC3DLayer.h"
31
32 #if USE(NICOSIA) && USE(TEXTURE_MAPPER)
33
34 #if USE(COORDINATED_GRAPHICS)
35 #include "TextureMapperGL.h"
36 #include "TextureMapperPlatformLayerBuffer.h"
37 #include "TextureMapperPlatformLayerProxy.h"
38 #endif
39
40 #if USE(ANGLE)
41 #include "ImageBuffer.h"
42 #endif
43
44 #include "GLContext.h"
45
46 namespace Nicosia {
47
48 using namespace WebCore;
49
50 GC3DLayer::GC3DLayer(GraphicsContext3D& context)
51     : m_context(context)
52     , m_contentLayer(Nicosia::ContentLayer::create(Nicosia::ContentLayerTextureMapperImpl::createFactory(*this)))
53 {
54 }
55
56 GC3DLayer::GC3DLayer(GraphicsContext3D& context, GraphicsContext3D::Destination destination)
57     : m_context(context)
58     , m_contentLayer(Nicosia::ContentLayer::create(Nicosia::ContentLayerTextureMapperImpl::createFactory(*this)))
59 {
60     switch (destination) {
61     case GraphicsContext3D::Destination::Offscreen:
62         m_glContext = GLContext::createOffscreenContext(&PlatformDisplay::sharedDisplayForCompositing());
63         break;
64     case GraphicsContext3D::Destination::DirectlyToHostWindow:
65         ASSERT_NOT_REACHED();
66         break;
67     }
68 }
69
70 GC3DLayer::~GC3DLayer()
71 {
72     downcast<ContentLayerTextureMapperImpl>(m_contentLayer->impl()).invalidateClient();
73 }
74
75 bool GC3DLayer::makeContextCurrent()
76 {
77     ASSERT(m_glContext);
78     return m_glContext->makeContextCurrent();
79 }
80
81 PlatformGraphicsContext3D GC3DLayer::platformContext() const
82 {
83     ASSERT(m_glContext);
84     return m_glContext->platformContext();
85 }
86
87 void GC3DLayer::swapBuffersIfNeeded()
88 {
89 #if USE(COORDINATED_GRAPHICS)
90     if (m_context.layerComposited())
91         return;
92
93     m_context.prepareTexture();
94     IntSize textureSize(m_context.m_currentWidth, m_context.m_currentHeight);
95     TextureMapperGL::Flags flags = m_context.contextAttributes().alpha ? TextureMapperGL::ShouldBlend : 0;
96 #if USE(ANGLE)
97     std::unique_ptr<ImageBuffer> imageBuffer = ImageBuffer::create(textureSize, Unaccelerated);
98     if (!imageBuffer)
99         return;
100
101     m_context.paintRenderingResultsToCanvas(imageBuffer.get());
102     RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore);
103     if (!image)
104         return;
105 #else
106     flags |= TextureMapperGL::ShouldFlipTexture;
107 #endif
108
109     {
110         auto& proxy = downcast<Nicosia::ContentLayerTextureMapperImpl>(m_contentLayer->impl()).proxy();
111 #if USE(ANGLE)
112         std::unique_ptr<TextureMapperPlatformLayerBuffer> layerBuffer;
113         layerBuffer = proxy.getAvailableBuffer(textureSize, m_context.m_internalColorFormat);
114         if (!layerBuffer) {
115             auto texture = BitmapTextureGL::create(TextureMapperContextAttributes::get(), flags, m_context.m_internalColorFormat);
116             static_cast<BitmapTextureGL&>(texture.get()).setPendingContents(WTFMove(image));
117             layerBuffer = makeUnique<TextureMapperPlatformLayerBuffer>(WTFMove(texture), flags);
118         } else
119             layerBuffer->textureGL().setPendingContents(WTFMove(image));
120
121         LockHolder holder(proxy.lock());
122         proxy.pushNextBuffer(WTFMove(layerBuffer));
123 #else
124         LockHolder holder(proxy.lock());
125         proxy.pushNextBuffer(makeUnique<TextureMapperPlatformLayerBuffer>(m_context.m_compositorTexture, textureSize, flags, m_context.m_internalColorFormat));
126 #endif
127     }
128
129     m_context.markLayerComposited();
130 #endif
131 }
132
133 } // namespace Nicosia
134
135 #endif // USE(NICOSIA) && USE(TEXTURE_MAPPER)