Assertion failed in JSC::createError
[WebKit-https.git] / Source / WebCore / html / canvas / WebMetalRenderingContext.cpp
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2017 Yuichiro Kikura (y.kikura@gmail.com)
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  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "WebMetalRenderingContext.h"
29
30 #if ENABLE(WEBMETAL)
31
32 #include "Document.h"
33 #include "FrameView.h"
34 #include "GPULegacyDevice.h"
35 #include "InspectorInstrumentation.h"
36 #include "WebMetalBuffer.h"
37 #include "WebMetalCommandQueue.h"
38 #include "WebMetalComputePipelineState.h"
39 #include "WebMetalDepthStencilDescriptor.h"
40 #include "WebMetalDepthStencilState.h"
41 #include "WebMetalDrawable.h"
42 #include "WebMetalFunction.h"
43 #include "WebMetalLibrary.h"
44 #include "WebMetalRenderPassDescriptor.h"
45 #include "WebMetalRenderPipelineDescriptor.h"
46 #include "WebMetalRenderPipelineState.h"
47 #include "WebMetalTexture.h"
48 #include "WebMetalTextureDescriptor.h"
49 #include <JavaScriptCore/ArrayBuffer.h>
50 #include <JavaScriptCore/JSCInlines.h>
51 #include <JavaScriptCore/TypedArrayInlines.h>
52 #include <JavaScriptCore/Uint32Array.h>
53 #include <wtf/StdLibExtras.h>
54 #include <wtf/text/CString.h>
55
56 namespace {
57
58 int clamp(int value, int min, int max)
59 {
60     if (value < min)
61         value = min;
62     if (value > max)
63         value = max;
64     return value;
65 }
66
67 }
68
69 namespace WebCore {
70
71 static const int kMaxTextureSize = 4096;
72
73 std::unique_ptr<WebMetalRenderingContext> WebMetalRenderingContext::create(CanvasBase& canvas)
74 {
75     GPULegacyDevice device;
76
77     if (!device) {
78         // FIXME: WebMetal - dispatch an event here for the failure.
79         return nullptr;
80     }
81
82     auto renderingContext = std::unique_ptr<WebMetalRenderingContext>(new WebMetalRenderingContext(canvas, WTFMove(device)));
83     renderingContext->suspendIfNeeded();
84
85     InspectorInstrumentation::didCreateCanvasRenderingContext(*renderingContext);
86
87     return renderingContext;
88 }
89
90 WebMetalRenderingContext::WebMetalRenderingContext(CanvasBase& canvas, GPULegacyDevice&& device)
91     : GPUBasedCanvasRenderingContext(canvas)
92     , m_device(WTFMove(device))
93 {
94     initializeNewContext();
95 }
96
97 HTMLCanvasElement* WebMetalRenderingContext::canvas() const
98 {
99     auto& base = canvasBase();
100     if (!is<HTMLCanvasElement>(base))
101         return nullptr;
102     return &downcast<HTMLCanvasElement>(base);
103 }
104
105 void WebMetalRenderingContext::initializeNewContext()
106 {
107     // FIXME: WebMetal - Maybe we should reset a bunch of stuff here.
108
109     IntSize canvasSize = clampedCanvasSize();
110     m_device.reshape(canvasSize.width(), canvasSize.height());
111 }
112
113 IntSize WebMetalRenderingContext::clampedCanvasSize() const
114 {
115     return IntSize(clamp(canvas()->width(), 1, kMaxTextureSize),
116         clamp(canvas()->height(), 1, kMaxTextureSize));
117 }
118
119 bool WebMetalRenderingContext::hasPendingActivity() const
120 {
121     return false;
122 }
123
124 void WebMetalRenderingContext::stop()
125 {
126 }
127
128 const char* WebMetalRenderingContext::activeDOMObjectName() const
129 {
130     return "WebMetalRenderingContext";
131 }
132
133 bool WebMetalRenderingContext::canSuspendForDocumentSuspension() const
134 {
135     return false;
136 }
137
138 PlatformLayer* WebMetalRenderingContext::platformLayer() const
139 {
140     return m_device.platformLayer();
141 }
142
143 void WebMetalRenderingContext::markLayerComposited()
144 {
145     m_device.markLayerComposited();
146 }
147
148 void WebMetalRenderingContext::reshape(int width, int height)
149 {
150     // FIXME: WebMetal - Do we need to reset stuff here?
151     m_device.reshape(width, height);
152 }
153
154 Ref<WebMetalLibrary> WebMetalRenderingContext::createLibrary(const String& sourceCode)
155 {
156     return WebMetalLibrary::create(GPULegacyLibrary { m_device, sourceCode }, sourceCode);
157 }
158
159 Ref<WebMetalRenderPipelineState> WebMetalRenderingContext::createRenderPipelineState(WebMetalRenderPipelineDescriptor& descriptor)
160 {
161     return WebMetalRenderPipelineState::create(GPULegacyRenderPipelineState { m_device, descriptor.descriptor() });
162 }
163
164 Ref<WebMetalDepthStencilState> WebMetalRenderingContext::createDepthStencilState(WebMetalDepthStencilDescriptor& descriptor)
165 {
166     return WebMetalDepthStencilState::create(GPULegacyDepthStencilState { m_device, descriptor.descriptor() });
167 }
168
169 Ref<WebMetalComputePipelineState> WebMetalRenderingContext::createComputePipelineState(WebMetalFunction& function)
170 {
171     return WebMetalComputePipelineState::create(GPULegacyComputePipelineState { m_device, function.function() });
172 }
173
174 Ref<WebMetalCommandQueue> WebMetalRenderingContext::createCommandQueue()
175 {
176     return WebMetalCommandQueue::create(GPULegacyCommandQueue { m_device });
177 }
178
179 Ref<WebMetalDrawable> WebMetalRenderingContext::nextDrawable()
180 {
181     return WebMetalDrawable::create(GPULegacyDrawable { m_device });
182 }
183
184 RefPtr<WebMetalBuffer> WebMetalRenderingContext::createBuffer(JSC::ArrayBufferView& data)
185 {
186     return WebMetalBuffer::create(GPULegacyBuffer { m_device, data });
187 }
188
189 Ref<WebMetalTexture> WebMetalRenderingContext::createTexture(WebMetalTextureDescriptor& descriptor)
190 {
191     return WebMetalTexture::create(GPULegacyTexture { m_device, descriptor.descriptor() });
192 }
193
194 } // namespace WebCore
195
196 #endif