| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2010 Apple Inc. All rights reserved. | |
| 3 * Copyright (C) 2010 Google Inc. All rights reserved. | |
| 4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. | |
| 5 * | |
| 6 * Redistribution and use in source and binary forms, with or without | |
| 7 * modification, are permitted provided that the following conditions | |
| 8 * are met: | |
| 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 copyright | |
| 12 * notice, this list of conditions and the following disclaimer in the | |
| 13 * documentation and/or other materials provided with the distribution. | |
| 14 * | |
| 15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
| 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
| 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 26 */ | |
| 27 | |
| 28 #include "config.h" | |
| 29 | |
| 30 #include "core/platform/graphics/GraphicsContext3D.h" | |
| 31 | |
| 32 #include "core/platform/graphics/GraphicsContext.h" | |
| 33 #include "core/platform/graphics/ImageBuffer.h" | |
| 34 #include "core/platform/graphics/gpu/DrawingBuffer.h" | |
| 35 #include "core/platform/image-decoders/ImageDecoder.h" | |
| 36 #include "platform/CheckedInt.h" | |
| 37 #include "platform/graphics/ImageObserver.h" | |
| 38 #include "third_party/skia/include/gpu/GrContext.h" | |
| 39 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" | |
| 40 #include "wtf/CPU.h" | |
| 41 #include "wtf/text/CString.h" | |
| 42 #include "wtf/text/StringHash.h" | |
| 43 | |
| 44 #include "public/platform/Platform.h" | |
| 45 #include "public/platform/WebGraphicsContext3D.h" | |
| 46 #include "public/platform/WebGraphicsContext3DProvider.h" | |
| 47 | |
| 48 namespace WebCore { | |
| 49 | |
| 50 namespace { | |
| 51 | |
| 52 void getDrawingParameters(DrawingBuffer* drawingBuffer, blink::WebGraphicsContex
t3D* graphicsContext3D, | |
| 53 Platform3DObject* frameBufferId, int* width, int* heig
ht) | |
| 54 { | |
| 55 ASSERT(drawingBuffer); | |
| 56 *frameBufferId = drawingBuffer->framebuffer(); | |
| 57 *width = drawingBuffer->size().width(); | |
| 58 *height = drawingBuffer->size().height(); | |
| 59 } | |
| 60 | |
| 61 } // anonymous namespace | |
| 62 | |
| 63 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<blink::WebGraphicsContext3D> web
Context, bool preserveDrawingBuffer) | |
| 64 : m_impl(webContext.get()) | |
| 65 , m_ownedWebContext(webContext) | |
| 66 , m_initializedAvailableExtensions(false) | |
| 67 , m_layerComposited(false) | |
| 68 , m_preserveDrawingBuffer(preserveDrawingBuffer) | |
| 69 , m_packAlignment(4) | |
| 70 , m_resourceSafety(ResourceSafetyUnknown) | |
| 71 , m_grContext(0) | |
| 72 { | |
| 73 } | |
| 74 | |
| 75 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<blink::WebGraphicsContext3DProvi
der> provider, bool preserveDrawingBuffer) | |
| 76 : m_provider(provider) | |
| 77 , m_impl(m_provider->context3d()) | |
| 78 , m_initializedAvailableExtensions(false) | |
| 79 , m_layerComposited(false) | |
| 80 , m_preserveDrawingBuffer(preserveDrawingBuffer) | |
| 81 , m_packAlignment(4) | |
| 82 , m_resourceSafety(ResourceSafetyUnknown) | |
| 83 , m_grContext(m_provider->grContext()) | |
| 84 { | |
| 85 } | |
| 86 | |
| 87 GraphicsContext3D::~GraphicsContext3D() | |
| 88 { | |
| 89 setContextLostCallback(nullptr); | |
| 90 setErrorMessageCallback(nullptr); | |
| 91 } | |
| 92 | |
| 93 // Macros to assist in delegating from GraphicsContext3D to | |
| 94 // WebGraphicsContext3D. | |
| 95 | |
| 96 #define DELEGATE_TO_WEBCONTEXT(name) \ | |
| 97 void GraphicsContext3D::name() \ | |
| 98 { \ | |
| 99 m_impl->name(); \ | |
| 100 } | |
| 101 | |
| 102 #define DELEGATE_TO_WEBCONTEXT_R(name, rt) \ | |
| 103 rt GraphicsContext3D::name() \ | |
| 104 { \ | |
| 105 return m_impl->name(); \ | |
| 106 } | |
| 107 | |
| 108 #define DELEGATE_TO_WEBCONTEXT_1(name, t1) \ | |
| 109 void GraphicsContext3D::name(t1 a1) \ | |
| 110 { \ | |
| 111 m_impl->name(a1); \ | |
| 112 } | |
| 113 | |
| 114 #define DELEGATE_TO_WEBCONTEXT_1R(name, t1, rt) \ | |
| 115 rt GraphicsContext3D::name(t1 a1) \ | |
| 116 { \ | |
| 117 return m_impl->name(a1); \ | |
| 118 } | |
| 119 | |
| 120 #define DELEGATE_TO_WEBCONTEXT_2(name, t1, t2) \ | |
| 121 void GraphicsContext3D::name(t1 a1, t2 a2) \ | |
| 122 { \ | |
| 123 m_impl->name(a1, a2); \ | |
| 124 } | |
| 125 | |
| 126 #define DELEGATE_TO_WEBCONTEXT_2R(name, t1, t2, rt) \ | |
| 127 rt GraphicsContext3D::name(t1 a1, t2 a2) \ | |
| 128 { \ | |
| 129 return m_impl->name(a1, a2); \ | |
| 130 } | |
| 131 | |
| 132 #define DELEGATE_TO_WEBCONTEXT_3(name, t1, t2, t3) \ | |
| 133 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ | |
| 134 { \ | |
| 135 m_impl->name(a1, a2, a3); \ | |
| 136 } | |
| 137 | |
| 138 #define DELEGATE_TO_WEBCONTEXT_3R(name, t1, t2, t3, rt) \ | |
| 139 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ | |
| 140 { \ | |
| 141 return m_impl->name(a1, a2, a3); \ | |
| 142 } | |
| 143 | |
| 144 #define DELEGATE_TO_WEBCONTEXT_4(name, t1, t2, t3, t4) \ | |
| 145 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ | |
| 146 { \ | |
| 147 m_impl->name(a1, a2, a3, a4); \ | |
| 148 } | |
| 149 | |
| 150 #define DELEGATE_TO_WEBCONTEXT_4R(name, t1, t2, t3, t4, rt) \ | |
| 151 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ | |
| 152 { \ | |
| 153 return m_impl->name(a1, a2, a3, a4); \ | |
| 154 } | |
| 155 | |
| 156 #define DELEGATE_TO_WEBCONTEXT_5(name, t1, t2, t3, t4, t5) \ | |
| 157 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ | |
| 158 { \ | |
| 159 m_impl->name(a1, a2, a3, a4, a5); \ | |
| 160 } | |
| 161 | |
| 162 #define DELEGATE_TO_WEBCONTEXT_6(name, t1, t2, t3, t4, t5, t6) \ | |
| 163 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ | |
| 164 { \ | |
| 165 m_impl->name(a1, a2, a3, a4, a5, a6); \ | |
| 166 } | |
| 167 | |
| 168 #define DELEGATE_TO_WEBCONTEXT_6R(name, t1, t2, t3, t4, t5, t6, rt) \ | |
| 169 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ | |
| 170 { \ | |
| 171 return m_impl->name(a1, a2, a3, a4, a5, a6); \ | |
| 172 } | |
| 173 | |
| 174 #define DELEGATE_TO_WEBCONTEXT_7(name, t1, t2, t3, t4, t5, t6, t7) \ | |
| 175 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ | |
| 176 { \ | |
| 177 m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ | |
| 178 } | |
| 179 | |
| 180 #define DELEGATE_TO_WEBCONTEXT_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \ | |
| 181 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ | |
| 182 { \ | |
| 183 return m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ | |
| 184 } | |
| 185 | |
| 186 #define DELEGATE_TO_WEBCONTEXT_8(name, t1, t2, t3, t4, t5, t6, t7, t8) \ | |
| 187 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8
a8) \ | |
| 188 { \ | |
| 189 m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8); \ | |
| 190 } | |
| 191 | |
| 192 #define DELEGATE_TO_WEBCONTEXT_9(name, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ | |
| 193 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8
a8, t9 a9) \ | |
| 194 { \ | |
| 195 m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ | |
| 196 } | |
| 197 | |
| 198 #define DELEGATE_TO_WEBCONTEXT_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt)
\ | |
| 199 rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a
8, t9 a9) \ | |
| 200 { \ | |
| 201 return m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ | |
| 202 } | |
| 203 | |
| 204 class GraphicsContext3DContextLostCallbackAdapter : public blink::WebGraphicsCon
text3D::WebGraphicsContextLostCallback { | |
| 205 public: | |
| 206 GraphicsContext3DContextLostCallbackAdapter(PassOwnPtr<GraphicsContext3D::Co
ntextLostCallback> callback) | |
| 207 : m_contextLostCallback(callback) { } | |
| 208 virtual ~GraphicsContext3DContextLostCallbackAdapter() { } | |
| 209 | |
| 210 virtual void onContextLost() | |
| 211 { | |
| 212 if (m_contextLostCallback) | |
| 213 m_contextLostCallback->onContextLost(); | |
| 214 } | |
| 215 private: | |
| 216 OwnPtr<GraphicsContext3D::ContextLostCallback> m_contextLostCallback; | |
| 217 }; | |
| 218 | |
| 219 class GraphicsContext3DErrorMessageCallbackAdapter : public blink::WebGraphicsCo
ntext3D::WebGraphicsErrorMessageCallback { | |
| 220 public: | |
| 221 GraphicsContext3DErrorMessageCallbackAdapter(PassOwnPtr<GraphicsContext3D::E
rrorMessageCallback> callback) | |
| 222 : m_errorMessageCallback(callback) { } | |
| 223 virtual ~GraphicsContext3DErrorMessageCallbackAdapter() { } | |
| 224 | |
| 225 virtual void onErrorMessage(const blink::WebString& message, blink::WGC3Dint
id) | |
| 226 { | |
| 227 if (m_errorMessageCallback) | |
| 228 m_errorMessageCallback->onErrorMessage(message, id); | |
| 229 } | |
| 230 private: | |
| 231 OwnPtr<GraphicsContext3D::ErrorMessageCallback> m_errorMessageCallback; | |
| 232 }; | |
| 233 | |
| 234 void GraphicsContext3D::setContextLostCallback(PassOwnPtr<GraphicsContext3D::Con
textLostCallback> callback) | |
| 235 { | |
| 236 if (m_ownedWebContext) { | |
| 237 m_contextLostCallbackAdapter = adoptPtr(new GraphicsContext3DContextLost
CallbackAdapter(callback)); | |
| 238 m_ownedWebContext->setContextLostCallback(m_contextLostCallbackAdapter.g
et()); | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 void GraphicsContext3D::setErrorMessageCallback(PassOwnPtr<GraphicsContext3D::Er
rorMessageCallback> callback) | |
| 243 { | |
| 244 if (m_ownedWebContext) { | |
| 245 m_errorMessageCallbackAdapter = adoptPtr(new GraphicsContext3DErrorMessa
geCallbackAdapter(callback)); | |
| 246 m_ownedWebContext->setErrorMessageCallback(m_errorMessageCallbackAdapter
.get()); | |
| 247 } | |
| 248 } | |
| 249 | |
| 250 PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attri
butes attrs) | |
| 251 { | |
| 252 blink::WebGraphicsContext3D::Attributes webAttributes; | |
| 253 webAttributes.alpha = attrs.alpha; | |
| 254 webAttributes.depth = attrs.depth; | |
| 255 webAttributes.stencil = attrs.stencil; | |
| 256 webAttributes.antialias = attrs.antialias; | |
| 257 webAttributes.premultipliedAlpha = attrs.premultipliedAlpha; | |
| 258 webAttributes.noExtensions = attrs.noExtensions; | |
| 259 webAttributes.shareResources = attrs.shareResources; | |
| 260 webAttributes.preferDiscreteGPU = attrs.preferDiscreteGPU; | |
| 261 webAttributes.failIfMajorPerformanceCaveat = attrs.failIfMajorPerformanceCav
eat; | |
| 262 webAttributes.topDocumentURL = attrs.topDocumentURL.string(); | |
| 263 | |
| 264 OwnPtr<blink::WebGraphicsContext3D> webContext = adoptPtr(blink::Platform::c
urrent()->createOffscreenGraphicsContext3D(webAttributes)); | |
| 265 if (!webContext) | |
| 266 return 0; | |
| 267 | |
| 268 return GraphicsContext3D::createGraphicsContextFromWebContext(webContext.rel
ease(), attrs.preserveDrawingBuffer); | |
| 269 } | |
| 270 | |
| 271 PassRefPtr<GraphicsContext3D> GraphicsContext3D::createGraphicsContextFromProvid
er(PassOwnPtr<blink::WebGraphicsContext3DProvider> provider, bool preserveDrawin
gBuffer) | |
| 272 { | |
| 273 RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(provider,
preserveDrawingBuffer)); | |
| 274 return context.release(); | |
| 275 } | |
| 276 | |
| 277 PassRefPtr<GraphicsContext3D> GraphicsContext3D::createGraphicsContextFromWebCon
text(PassOwnPtr<blink::WebGraphicsContext3D> webContext, bool preserveDrawingBuf
fer) | |
| 278 { | |
| 279 RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(webContex
t, preserveDrawingBuffer)); | |
| 280 return context.release(); | |
| 281 } | |
| 282 | |
| 283 GrContext* GraphicsContext3D::grContext() | |
| 284 { | |
| 285 return m_grContext; | |
| 286 } | |
| 287 | |
| 288 DELEGATE_TO_WEBCONTEXT_R(makeContextCurrent, bool) | |
| 289 DELEGATE_TO_WEBCONTEXT_R(lastFlushID, uint32_t) | |
| 290 | |
| 291 DELEGATE_TO_WEBCONTEXT_1(activeTexture, GC3Denum) | |
| 292 DELEGATE_TO_WEBCONTEXT_2(attachShader, Platform3DObject, Platform3DObject) | |
| 293 | |
| 294 void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint in
dex, const String& name) | |
| 295 { | |
| 296 m_impl->bindAttribLocation(program, index, name.utf8().data()); | |
| 297 } | |
| 298 | |
| 299 DELEGATE_TO_WEBCONTEXT_2(bindBuffer, GC3Denum, Platform3DObject) | |
| 300 DELEGATE_TO_WEBCONTEXT_2(bindFramebuffer, GC3Denum, Platform3DObject) | |
| 301 DELEGATE_TO_WEBCONTEXT_2(bindRenderbuffer, GC3Denum, Platform3DObject) | |
| 302 DELEGATE_TO_WEBCONTEXT_2(bindTexture, GC3Denum, Platform3DObject) | |
| 303 DELEGATE_TO_WEBCONTEXT_4(blendColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dcla
mpf) | |
| 304 DELEGATE_TO_WEBCONTEXT_1(blendEquation, GC3Denum) | |
| 305 DELEGATE_TO_WEBCONTEXT_2(blendEquationSeparate, GC3Denum, GC3Denum) | |
| 306 DELEGATE_TO_WEBCONTEXT_2(blendFunc, GC3Denum, GC3Denum) | |
| 307 DELEGATE_TO_WEBCONTEXT_4(blendFuncSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Den
um) | |
| 308 | |
| 309 void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum
usage) | |
| 310 { | |
| 311 bufferData(target, size, 0, usage); | |
| 312 } | |
| 313 | |
| 314 DELEGATE_TO_WEBCONTEXT_4(bufferData, GC3Denum, GC3Dsizeiptr, const void*, GC3Den
um) | |
| 315 DELEGATE_TO_WEBCONTEXT_4(bufferSubData, GC3Denum, GC3Dintptr, GC3Dsizeiptr, cons
t void*) | |
| 316 | |
| 317 DELEGATE_TO_WEBCONTEXT_1R(checkFramebufferStatus, GC3Denum, GC3Denum) | |
| 318 DELEGATE_TO_WEBCONTEXT_1(clear, GC3Dbitfield) | |
| 319 DELEGATE_TO_WEBCONTEXT_4(clearColor, GC3Dclampf, GC3Dclampf, GC3Dclampf, GC3Dcla
mpf) | |
| 320 DELEGATE_TO_WEBCONTEXT_1(clearDepth, GC3Dclampf) | |
| 321 DELEGATE_TO_WEBCONTEXT_1(clearStencil, GC3Dint) | |
| 322 DELEGATE_TO_WEBCONTEXT_4(colorMask, GC3Dboolean, GC3Dboolean, GC3Dboolean, GC3Db
oolean) | |
| 323 DELEGATE_TO_WEBCONTEXT_1(compileShader, Platform3DObject) | |
| 324 | |
| 325 DELEGATE_TO_WEBCONTEXT_8(compressedTexImage2D, GC3Denum, GC3Dint, GC3Denum, GC3D
int, GC3Dint, GC3Dsizei, GC3Dsizei, const void*) | |
| 326 DELEGATE_TO_WEBCONTEXT_9(compressedTexSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC
3Dint, GC3Dint, GC3Dint, GC3Denum, GC3Dsizei, const void*) | |
| 327 DELEGATE_TO_WEBCONTEXT_8(copyTexImage2D, GC3Denum, GC3Dint, GC3Denum, GC3Dint, G
C3Dint, GC3Dsizei, GC3Dsizei, GC3Dint) | |
| 328 DELEGATE_TO_WEBCONTEXT_8(copyTexSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC3Dint,
GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | |
| 329 DELEGATE_TO_WEBCONTEXT_1(cullFace, GC3Denum) | |
| 330 DELEGATE_TO_WEBCONTEXT_1(depthFunc, GC3Denum) | |
| 331 DELEGATE_TO_WEBCONTEXT_1(depthMask, GC3Dboolean) | |
| 332 DELEGATE_TO_WEBCONTEXT_2(depthRange, GC3Dclampf, GC3Dclampf) | |
| 333 DELEGATE_TO_WEBCONTEXT_2(detachShader, Platform3DObject, Platform3DObject) | |
| 334 DELEGATE_TO_WEBCONTEXT_1(disable, GC3Denum) | |
| 335 DELEGATE_TO_WEBCONTEXT_1(disableVertexAttribArray, GC3Duint) | |
| 336 DELEGATE_TO_WEBCONTEXT_3(drawArrays, GC3Denum, GC3Dint, GC3Dsizei) | |
| 337 DELEGATE_TO_WEBCONTEXT_4(drawElements, GC3Denum, GC3Dsizei, GC3Denum, GC3Dintptr
) | |
| 338 | |
| 339 DELEGATE_TO_WEBCONTEXT_1(enable, GC3Denum) | |
| 340 DELEGATE_TO_WEBCONTEXT_1(enableVertexAttribArray, GC3Duint) | |
| 341 DELEGATE_TO_WEBCONTEXT(finish) | |
| 342 DELEGATE_TO_WEBCONTEXT(flush) | |
| 343 DELEGATE_TO_WEBCONTEXT_4(framebufferRenderbuffer, GC3Denum, GC3Denum, GC3Denum,
Platform3DObject) | |
| 344 DELEGATE_TO_WEBCONTEXT_5(framebufferTexture2D, GC3Denum, GC3Denum, GC3Denum, Pla
tform3DObject, GC3Dint) | |
| 345 DELEGATE_TO_WEBCONTEXT_1(frontFace, GC3Denum) | |
| 346 DELEGATE_TO_WEBCONTEXT_1(generateMipmap, GC3Denum) | |
| 347 | |
| 348 bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index
, ActiveInfo& info) | |
| 349 { | |
| 350 blink::WebGraphicsContext3D::ActiveInfo webInfo; | |
| 351 if (!m_impl->getActiveAttrib(program, index, webInfo)) | |
| 352 return false; | |
| 353 info.name = webInfo.name; | |
| 354 info.type = webInfo.type; | |
| 355 info.size = webInfo.size; | |
| 356 return true; | |
| 357 } | |
| 358 | |
| 359 bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint inde
x, ActiveInfo& info) | |
| 360 { | |
| 361 blink::WebGraphicsContext3D::ActiveInfo webInfo; | |
| 362 if (!m_impl->getActiveUniform(program, index, webInfo)) | |
| 363 return false; | |
| 364 info.name = webInfo.name; | |
| 365 info.type = webInfo.type; | |
| 366 info.size = webInfo.size; | |
| 367 return true; | |
| 368 } | |
| 369 | |
| 370 DELEGATE_TO_WEBCONTEXT_4(getAttachedShaders, Platform3DObject, GC3Dsizei, GC3Dsi
zei*, Platform3DObject*) | |
| 371 | |
| 372 GC3Dint GraphicsContext3D::getAttribLocation(Platform3DObject program, const Str
ing& name) | |
| 373 { | |
| 374 return m_impl->getAttribLocation(program, name.utf8().data()); | |
| 375 } | |
| 376 | |
| 377 DELEGATE_TO_WEBCONTEXT_2(getBooleanv, GC3Denum, GC3Dboolean*) | |
| 378 DELEGATE_TO_WEBCONTEXT_3(getBufferParameteriv, GC3Denum, GC3Denum, GC3Dint*) | |
| 379 | |
| 380 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() | |
| 381 { | |
| 382 blink::WebGraphicsContext3D::Attributes webAttributes = m_impl->getContextAt
tributes(); | |
| 383 GraphicsContext3D::Attributes attributes; | |
| 384 attributes.alpha = webAttributes.alpha; | |
| 385 attributes.depth = webAttributes.depth; | |
| 386 attributes.stencil = webAttributes.stencil; | |
| 387 attributes.antialias = webAttributes.antialias; | |
| 388 attributes.premultipliedAlpha = webAttributes.premultipliedAlpha; | |
| 389 attributes.preserveDrawingBuffer = m_preserveDrawingBuffer; | |
| 390 attributes.preferDiscreteGPU = webAttributes.preferDiscreteGPU; | |
| 391 return attributes; | |
| 392 } | |
| 393 | |
| 394 DELEGATE_TO_WEBCONTEXT_R(getError, GC3Denum) | |
| 395 DELEGATE_TO_WEBCONTEXT_2(getFloatv, GC3Denum, GC3Dfloat*) | |
| 396 DELEGATE_TO_WEBCONTEXT_4(getFramebufferAttachmentParameteriv, GC3Denum, GC3Denum
, GC3Denum, GC3Dint*) | |
| 397 DELEGATE_TO_WEBCONTEXT_2(getIntegerv, GC3Denum, GC3Dint*) | |
| 398 DELEGATE_TO_WEBCONTEXT_3(getProgramiv, Platform3DObject, GC3Denum, GC3Dint*) | |
| 399 DELEGATE_TO_WEBCONTEXT_1R(getProgramInfoLog, Platform3DObject, String) | |
| 400 DELEGATE_TO_WEBCONTEXT_3(getRenderbufferParameteriv, GC3Denum, GC3Denum, GC3Dint
*) | |
| 401 DELEGATE_TO_WEBCONTEXT_3(getShaderiv, Platform3DObject, GC3Denum, GC3Dint*) | |
| 402 DELEGATE_TO_WEBCONTEXT_1R(getShaderInfoLog, Platform3DObject, String) | |
| 403 DELEGATE_TO_WEBCONTEXT_4(getShaderPrecisionFormat, GC3Denum, GC3Denum, GC3Dint*,
GC3Dint*) | |
| 404 DELEGATE_TO_WEBCONTEXT_1R(getShaderSource, Platform3DObject, String) | |
| 405 DELEGATE_TO_WEBCONTEXT_1R(getString, GC3Denum, String) | |
| 406 DELEGATE_TO_WEBCONTEXT_3(getTexParameterfv, GC3Denum, GC3Denum, GC3Dfloat*) | |
| 407 DELEGATE_TO_WEBCONTEXT_3(getTexParameteriv, GC3Denum, GC3Denum, GC3Dint*) | |
| 408 DELEGATE_TO_WEBCONTEXT_3(getUniformfv, Platform3DObject, GC3Dint, GC3Dfloat*) | |
| 409 DELEGATE_TO_WEBCONTEXT_3(getUniformiv, Platform3DObject, GC3Dint, GC3Dint*) | |
| 410 | |
| 411 GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const St
ring& name) | |
| 412 { | |
| 413 return m_impl->getUniformLocation(program, name.utf8().data()); | |
| 414 } | |
| 415 | |
| 416 DELEGATE_TO_WEBCONTEXT_3(getVertexAttribfv, GC3Duint, GC3Denum, GC3Dfloat*) | |
| 417 DELEGATE_TO_WEBCONTEXT_3(getVertexAttribiv, GC3Duint, GC3Denum, GC3Dint*) | |
| 418 DELEGATE_TO_WEBCONTEXT_2R(getVertexAttribOffset, GC3Duint, GC3Denum, GC3Dsizeipt
r) | |
| 419 | |
| 420 DELEGATE_TO_WEBCONTEXT_2(hint, GC3Denum, GC3Denum) | |
| 421 DELEGATE_TO_WEBCONTEXT_1R(isBuffer, Platform3DObject, GC3Dboolean) | |
| 422 DELEGATE_TO_WEBCONTEXT_1R(isEnabled, GC3Denum, GC3Dboolean) | |
| 423 DELEGATE_TO_WEBCONTEXT_1R(isFramebuffer, Platform3DObject, GC3Dboolean) | |
| 424 DELEGATE_TO_WEBCONTEXT_1R(isProgram, Platform3DObject, GC3Dboolean) | |
| 425 DELEGATE_TO_WEBCONTEXT_1R(isRenderbuffer, Platform3DObject, GC3Dboolean) | |
| 426 DELEGATE_TO_WEBCONTEXT_1R(isShader, Platform3DObject, GC3Dboolean) | |
| 427 DELEGATE_TO_WEBCONTEXT_1R(isTexture, Platform3DObject, GC3Dboolean) | |
| 428 DELEGATE_TO_WEBCONTEXT_1(lineWidth, GC3Dfloat) | |
| 429 DELEGATE_TO_WEBCONTEXT_1(linkProgram, Platform3DObject) | |
| 430 | |
| 431 void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param) | |
| 432 { | |
| 433 if (pname == PACK_ALIGNMENT) | |
| 434 m_packAlignment = param; | |
| 435 m_impl->pixelStorei(pname, param); | |
| 436 } | |
| 437 | |
| 438 DELEGATE_TO_WEBCONTEXT_2(polygonOffset, GC3Dfloat, GC3Dfloat) | |
| 439 | |
| 440 DELEGATE_TO_WEBCONTEXT_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3
Denum, GC3Denum, void*) | |
| 441 | |
| 442 DELEGATE_TO_WEBCONTEXT(releaseShaderCompiler) | |
| 443 DELEGATE_TO_WEBCONTEXT_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3
Dsizei) | |
| 444 DELEGATE_TO_WEBCONTEXT_2(sampleCoverage, GC3Dclampf, GC3Dboolean) | |
| 445 DELEGATE_TO_WEBCONTEXT_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | |
| 446 | |
| 447 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& stri
ng) | |
| 448 { | |
| 449 m_impl->shaderSource(shader, string.utf8().data()); | |
| 450 } | |
| 451 | |
| 452 DELEGATE_TO_WEBCONTEXT_3(stencilFunc, GC3Denum, GC3Dint, GC3Duint) | |
| 453 DELEGATE_TO_WEBCONTEXT_4(stencilFuncSeparate, GC3Denum, GC3Denum, GC3Dint, GC3Du
int) | |
| 454 DELEGATE_TO_WEBCONTEXT_1(stencilMask, GC3Duint) | |
| 455 DELEGATE_TO_WEBCONTEXT_2(stencilMaskSeparate, GC3Denum, GC3Duint) | |
| 456 DELEGATE_TO_WEBCONTEXT_3(stencilOp, GC3Denum, GC3Denum, GC3Denum) | |
| 457 DELEGATE_TO_WEBCONTEXT_4(stencilOpSeparate, GC3Denum, GC3Denum, GC3Denum, GC3Den
um) | |
| 458 | |
| 459 DELEGATE_TO_WEBCONTEXT_9(texImage2D, GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3
Dsizei, GC3Dint, GC3Denum, GC3Denum, const void*) | |
| 460 DELEGATE_TO_WEBCONTEXT_3(texParameterf, GC3Denum, GC3Denum, GC3Dfloat) | |
| 461 DELEGATE_TO_WEBCONTEXT_3(texParameteri, GC3Denum, GC3Denum, GC3Dint) | |
| 462 DELEGATE_TO_WEBCONTEXT_9(texSubImage2D, GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3
Dsizei, GC3Dsizei, GC3Denum, GC3Denum, const void*) | |
| 463 | |
| 464 DELEGATE_TO_WEBCONTEXT_2(uniform1f, GC3Dint, GC3Dfloat) | |
| 465 DELEGATE_TO_WEBCONTEXT_3(uniform1fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
| 466 DELEGATE_TO_WEBCONTEXT_2(uniform1i, GC3Dint, GC3Dint) | |
| 467 DELEGATE_TO_WEBCONTEXT_3(uniform1iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
| 468 DELEGATE_TO_WEBCONTEXT_3(uniform2f, GC3Dint, GC3Dfloat, GC3Dfloat) | |
| 469 DELEGATE_TO_WEBCONTEXT_3(uniform2fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
| 470 DELEGATE_TO_WEBCONTEXT_3(uniform2i, GC3Dint, GC3Dint, GC3Dint) | |
| 471 DELEGATE_TO_WEBCONTEXT_3(uniform2iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
| 472 DELEGATE_TO_WEBCONTEXT_4(uniform3f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat) | |
| 473 DELEGATE_TO_WEBCONTEXT_3(uniform3fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
| 474 DELEGATE_TO_WEBCONTEXT_4(uniform3i, GC3Dint, GC3Dint, GC3Dint, GC3Dint) | |
| 475 DELEGATE_TO_WEBCONTEXT_3(uniform3iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
| 476 DELEGATE_TO_WEBCONTEXT_5(uniform4f, GC3Dint, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC
3Dfloat) | |
| 477 DELEGATE_TO_WEBCONTEXT_3(uniform4fv, GC3Dint, GC3Dsizei, GC3Dfloat*) | |
| 478 DELEGATE_TO_WEBCONTEXT_5(uniform4i, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint) | |
| 479 DELEGATE_TO_WEBCONTEXT_3(uniform4iv, GC3Dint, GC3Dsizei, GC3Dint*) | |
| 480 DELEGATE_TO_WEBCONTEXT_4(uniformMatrix2fv, GC3Dint, GC3Dsizei, GC3Dboolean, GC3D
float*) | |
| 481 DELEGATE_TO_WEBCONTEXT_4(uniformMatrix3fv, GC3Dint, GC3Dsizei, GC3Dboolean, GC3D
float*) | |
| 482 DELEGATE_TO_WEBCONTEXT_4(uniformMatrix4fv, GC3Dint, GC3Dsizei, GC3Dboolean, GC3D
float*) | |
| 483 | |
| 484 DELEGATE_TO_WEBCONTEXT_1(useProgram, Platform3DObject) | |
| 485 DELEGATE_TO_WEBCONTEXT_1(validateProgram, Platform3DObject) | |
| 486 | |
| 487 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib1f, GC3Duint, GC3Dfloat) | |
| 488 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib1fv, GC3Duint, GC3Dfloat*) | |
| 489 DELEGATE_TO_WEBCONTEXT_3(vertexAttrib2f, GC3Duint, GC3Dfloat, GC3Dfloat) | |
| 490 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib2fv, GC3Duint, GC3Dfloat*) | |
| 491 DELEGATE_TO_WEBCONTEXT_4(vertexAttrib3f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dflo
at) | |
| 492 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib3fv, GC3Duint, GC3Dfloat*) | |
| 493 DELEGATE_TO_WEBCONTEXT_5(vertexAttrib4f, GC3Duint, GC3Dfloat, GC3Dfloat, GC3Dflo
at, GC3Dfloat) | |
| 494 DELEGATE_TO_WEBCONTEXT_2(vertexAttrib4fv, GC3Duint, GC3Dfloat*) | |
| 495 DELEGATE_TO_WEBCONTEXT_6(vertexAttribPointer, GC3Duint, GC3Dint, GC3Denum, GC3Db
oolean, GC3Dsizei, GC3Dintptr) | |
| 496 | |
| 497 DELEGATE_TO_WEBCONTEXT_4(viewport, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | |
| 498 | |
| 499 void GraphicsContext3D::markContextChanged() | |
| 500 { | |
| 501 m_layerComposited = false; | |
| 502 } | |
| 503 | |
| 504 bool GraphicsContext3D::layerComposited() const | |
| 505 { | |
| 506 return m_layerComposited; | |
| 507 } | |
| 508 | |
| 509 void GraphicsContext3D::markLayerComposited() | |
| 510 { | |
| 511 m_layerComposited = true; | |
| 512 } | |
| 513 | |
| 514 void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer,
DrawingBuffer* drawingBuffer) | |
| 515 { | |
| 516 Platform3DObject framebufferId; | |
| 517 int width, height; | |
| 518 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; | |
| 519 paintFramebufferToCanvas(framebufferId, width, height, !getContextAttributes
().premultipliedAlpha, imageBuffer); | |
| 520 } | |
| 521 | |
| 522 PassRefPtr<Uint8ClampedArray> GraphicsContext3D::paintRenderingResultsToImageDat
a(DrawingBuffer* drawingBuffer, int& width, int& height) | |
| 523 { | |
| 524 if (getContextAttributes().premultipliedAlpha) | |
| 525 return 0; | |
| 526 | |
| 527 Platform3DObject framebufferId; | |
| 528 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; | |
| 529 | |
| 530 Checked<int, RecordOverflow> dataSize = 4; | |
| 531 dataSize *= width; | |
| 532 dataSize *= height; | |
| 533 if (dataSize.hasOverflowed()) | |
| 534 return 0; | |
| 535 | |
| 536 RefPtr<Uint8ClampedArray> pixels = Uint8ClampedArray::createUninitialized(wi
dth * height * 4); | |
| 537 | |
| 538 m_impl->bindFramebuffer(FRAMEBUFFER, framebufferId); | |
| 539 readBackFramebuffer(pixels->data(), width, height, ReadbackRGBA, AlphaDoNoth
ing); | |
| 540 flipVertically(pixels->data(), width, height); | |
| 541 | |
| 542 return pixels.release(); | |
| 543 } | |
| 544 | |
| 545 void GraphicsContext3D::readBackFramebuffer(unsigned char* pixels, int width, in
t height, ReadbackOrder readbackOrder, AlphaOp op) | |
| 546 { | |
| 547 if (m_packAlignment > 4) | |
| 548 m_impl->pixelStorei(PACK_ALIGNMENT, 1); | |
| 549 m_impl->readPixels(0, 0, width, height, RGBA, UNSIGNED_BYTE, pixels); | |
| 550 if (m_packAlignment > 4) | |
| 551 m_impl->pixelStorei(PACK_ALIGNMENT, m_packAlignment); | |
| 552 | |
| 553 size_t bufferSize = 4 * width * height; | |
| 554 | |
| 555 if (readbackOrder == ReadbackSkia) { | |
| 556 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | |
| 557 // Swizzle red and blue channels to match SkBitmap's byte ordering. | |
| 558 // TODO(kbr): expose GL_BGRA as extension. | |
| 559 for (size_t i = 0; i < bufferSize; i += 4) { | |
| 560 std::swap(pixels[i], pixels[i + 2]); | |
| 561 } | |
| 562 #endif | |
| 563 } | |
| 564 | |
| 565 if (op == AlphaDoPremultiply) { | |
| 566 for (size_t i = 0; i < bufferSize; i += 4) { | |
| 567 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); | |
| 568 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); | |
| 569 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); | |
| 570 } | |
| 571 } else if (op != AlphaDoNothing) { | |
| 572 ASSERT_NOT_REACHED(); | |
| 573 } | |
| 574 } | |
| 575 | |
| 576 DELEGATE_TO_WEBCONTEXT_R(createBuffer, Platform3DObject) | |
| 577 DELEGATE_TO_WEBCONTEXT_R(createFramebuffer, Platform3DObject) | |
| 578 DELEGATE_TO_WEBCONTEXT_R(createProgram, Platform3DObject) | |
| 579 DELEGATE_TO_WEBCONTEXT_R(createRenderbuffer, Platform3DObject) | |
| 580 DELEGATE_TO_WEBCONTEXT_1R(createShader, GC3Denum, Platform3DObject) | |
| 581 DELEGATE_TO_WEBCONTEXT_R(createTexture, Platform3DObject) | |
| 582 | |
| 583 DELEGATE_TO_WEBCONTEXT_1(deleteBuffer, Platform3DObject) | |
| 584 DELEGATE_TO_WEBCONTEXT_1(deleteFramebuffer, Platform3DObject) | |
| 585 DELEGATE_TO_WEBCONTEXT_1(deleteProgram, Platform3DObject) | |
| 586 DELEGATE_TO_WEBCONTEXT_1(deleteRenderbuffer, Platform3DObject) | |
| 587 DELEGATE_TO_WEBCONTEXT_1(deleteShader, Platform3DObject) | |
| 588 DELEGATE_TO_WEBCONTEXT_1(deleteTexture, Platform3DObject) | |
| 589 | |
| 590 DELEGATE_TO_WEBCONTEXT_1(synthesizeGLError, GC3Denum) | |
| 591 | |
| 592 Extensions3D* GraphicsContext3D::extensions() | |
| 593 { | |
| 594 if (!m_extensions) | |
| 595 m_extensions = adoptPtr(new Extensions3D(this)); | |
| 596 return m_extensions.get(); | |
| 597 } | |
| 598 | |
| 599 bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, G
C3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3De
num format, GC3Denum type, GC3Dint unpackAlignment) | |
| 600 { | |
| 601 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4
|| unpackAlignment == 8); | |
| 602 texImage2D(target, level, internalformat, width, height, border, format, typ
e, 0); | |
| 603 return true; | |
| 604 } | |
| 605 | |
| 606 bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, | |
| 607 GC3Denum type, | |
| 608 unsigned int* componentsP
erPixel, | |
| 609 unsigned int* bytesPerCom
ponent) | |
| 610 { | |
| 611 switch (format) { | |
| 612 case GraphicsContext3D::ALPHA: | |
| 613 case GraphicsContext3D::LUMINANCE: | |
| 614 case GraphicsContext3D::DEPTH_COMPONENT: | |
| 615 case GraphicsContext3D::DEPTH_STENCIL: | |
| 616 *componentsPerPixel = 1; | |
| 617 break; | |
| 618 case GraphicsContext3D::LUMINANCE_ALPHA: | |
| 619 *componentsPerPixel = 2; | |
| 620 break; | |
| 621 case GraphicsContext3D::RGB: | |
| 622 *componentsPerPixel = 3; | |
| 623 break; | |
| 624 case GraphicsContext3D::RGBA: | |
| 625 case Extensions3D::BGRA_EXT: // GL_EXT_texture_format_BGRA8888 | |
| 626 *componentsPerPixel = 4; | |
| 627 break; | |
| 628 default: | |
| 629 return false; | |
| 630 } | |
| 631 switch (type) { | |
| 632 case GraphicsContext3D::UNSIGNED_BYTE: | |
| 633 *bytesPerComponent = sizeof(GC3Dubyte); | |
| 634 break; | |
| 635 case GraphicsContext3D::UNSIGNED_SHORT: | |
| 636 *bytesPerComponent = sizeof(GC3Dushort); | |
| 637 break; | |
| 638 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: | |
| 639 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: | |
| 640 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: | |
| 641 *componentsPerPixel = 1; | |
| 642 *bytesPerComponent = sizeof(GC3Dushort); | |
| 643 break; | |
| 644 case GraphicsContext3D::UNSIGNED_INT_24_8: | |
| 645 case GraphicsContext3D::UNSIGNED_INT: | |
| 646 *bytesPerComponent = sizeof(GC3Duint); | |
| 647 break; | |
| 648 case GraphicsContext3D::FLOAT: // OES_texture_float | |
| 649 *bytesPerComponent = sizeof(GC3Dfloat); | |
| 650 break; | |
| 651 case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float | |
| 652 *bytesPerComponent = sizeof(GC3Dhalffloat); | |
| 653 break; | |
| 654 default: | |
| 655 return false; | |
| 656 } | |
| 657 return true; | |
| 658 } | |
| 659 | |
| 660 GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum ty
pe, GC3Dsizei width, GC3Dsizei height, GC3Dint alignment, | |
| 661 unsigned int* imageSizeInByt
es, unsigned int* paddingInBytes) | |
| 662 { | |
| 663 ASSERT(imageSizeInBytes); | |
| 664 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8)
; | |
| 665 if (width < 0 || height < 0) | |
| 666 return GraphicsContext3D::INVALID_VALUE; | |
| 667 unsigned int bytesPerComponent, componentsPerPixel; | |
| 668 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo
nentsPerPixel)) | |
| 669 return GraphicsContext3D::INVALID_ENUM; | |
| 670 if (!width || !height) { | |
| 671 *imageSizeInBytes = 0; | |
| 672 if (paddingInBytes) | |
| 673 *paddingInBytes = 0; | |
| 674 return GraphicsContext3D::NO_ERROR; | |
| 675 } | |
| 676 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel); | |
| 677 checkedValue *= width; | |
| 678 if (!checkedValue.isValid()) | |
| 679 return GraphicsContext3D::INVALID_VALUE; | |
| 680 unsigned int validRowSize = checkedValue.value(); | |
| 681 unsigned int padding = 0; | |
| 682 unsigned int residual = validRowSize % alignment; | |
| 683 if (residual) { | |
| 684 padding = alignment - residual; | |
| 685 checkedValue += padding; | |
| 686 } | |
| 687 // Last row needs no padding. | |
| 688 checkedValue *= (height - 1); | |
| 689 checkedValue += validRowSize; | |
| 690 if (!checkedValue.isValid()) | |
| 691 return GraphicsContext3D::INVALID_VALUE; | |
| 692 *imageSizeInBytes = checkedValue.value(); | |
| 693 if (paddingInBytes) | |
| 694 *paddingInBytes = padding; | |
| 695 return GraphicsContext3D::NO_ERROR; | |
| 696 } | |
| 697 | |
| 698 GraphicsContext3D::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomSour
ce imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile) | |
| 699 { | |
| 700 m_image = image; | |
| 701 m_imageHtmlDomSource = imageHtmlDomSource; | |
| 702 m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfi
le); | |
| 703 } | |
| 704 | |
| 705 GraphicsContext3D::ImageExtractor::~ImageExtractor() | |
| 706 { | |
| 707 if (m_skiaImage) | |
| 708 m_skiaImage->bitmap().unlockPixels(); | |
| 709 } | |
| 710 | |
| 711 bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool
ignoreGammaAndColorProfile) | |
| 712 { | |
| 713 if (!m_image) | |
| 714 return false; | |
| 715 m_skiaImage = m_image->nativeImageForCurrentFrame(); | |
| 716 m_alphaOp = AlphaDoNothing; | |
| 717 bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true; | |
| 718 if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiply
Alpha)) && m_image->data()) { | |
| 719 // Attempt to get raw unpremultiplied image data. | |
| 720 OwnPtr<ImageDecoder> decoder(ImageDecoder::create( | |
| 721 *(m_image->data()), ImageSource::AlphaNotPremultiplied, | |
| 722 ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnore
d : ImageSource::GammaAndColorProfileApplied)); | |
| 723 if (!decoder) | |
| 724 return false; | |
| 725 decoder->setData(m_image->data(), true); | |
| 726 if (!decoder->frameCount()) | |
| 727 return false; | |
| 728 ImageFrame* frame = decoder->frameBufferAtIndex(0); | |
| 729 if (!frame || frame->status() != ImageFrame::FrameComplete) | |
| 730 return false; | |
| 731 hasAlpha = frame->hasAlpha(); | |
| 732 m_nativeImage = frame->asNewNativeImage(); | |
| 733 if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativ
eImage->bitmap().width() || !m_nativeImage->bitmap().height()) | |
| 734 return false; | |
| 735 SkBitmap::Config skiaConfig = m_nativeImage->bitmap().config(); | |
| 736 if (skiaConfig != SkBitmap::kARGB_8888_Config) | |
| 737 return false; | |
| 738 m_skiaImage = m_nativeImage.get(); | |
| 739 if (hasAlpha && premultiplyAlpha) | |
| 740 m_alphaOp = AlphaDoPremultiply; | |
| 741 } else if (!premultiplyAlpha && hasAlpha) { | |
| 742 // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAl
pha had been applied and the alpha value for each pixel is 0xFF | |
| 743 // which is true at present and may be changed in the future and needs a
djustment accordingly. | |
| 744 // 2. For texImage2D with HTMLCanvasElement input in which Alpha is alre
ady Premultiplied in this port, | |
| 745 // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to fals
e. | |
| 746 if (m_imageHtmlDomSource != HtmlDomVideo) | |
| 747 m_alphaOp = AlphaDoUnmultiply; | |
| 748 } | |
| 749 if (!m_skiaImage) | |
| 750 return false; | |
| 751 | |
| 752 m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8; | |
| 753 m_imageWidth = m_skiaImage->bitmap().width(); | |
| 754 m_imageHeight = m_skiaImage->bitmap().height(); | |
| 755 if (!m_imageWidth || !m_imageHeight) | |
| 756 return false; | |
| 757 m_imageSourceUnpackAlignment = 0; | |
| 758 m_skiaImage->bitmap().lockPixels(); | |
| 759 m_imagePixelData = m_skiaImage->bitmap().getPixels(); | |
| 760 return true; | |
| 761 } | |
| 762 | |
| 763 unsigned GraphicsContext3D::getClearBitsByFormat(GC3Denum format) | |
| 764 { | |
| 765 switch (format) { | |
| 766 case GraphicsContext3D::ALPHA: | |
| 767 case GraphicsContext3D::LUMINANCE: | |
| 768 case GraphicsContext3D::LUMINANCE_ALPHA: | |
| 769 case GraphicsContext3D::RGB: | |
| 770 case GraphicsContext3D::RGB565: | |
| 771 case GraphicsContext3D::RGBA: | |
| 772 case GraphicsContext3D::RGBA4: | |
| 773 case GraphicsContext3D::RGB5_A1: | |
| 774 return GraphicsContext3D::COLOR_BUFFER_BIT; | |
| 775 case GraphicsContext3D::DEPTH_COMPONENT16: | |
| 776 case GraphicsContext3D::DEPTH_COMPONENT: | |
| 777 return GraphicsContext3D::DEPTH_BUFFER_BIT; | |
| 778 case GraphicsContext3D::STENCIL_INDEX8: | |
| 779 return GraphicsContext3D::STENCIL_BUFFER_BIT; | |
| 780 case GraphicsContext3D::DEPTH_STENCIL: | |
| 781 return GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_
BUFFER_BIT; | |
| 782 default: | |
| 783 return 0; | |
| 784 } | |
| 785 } | |
| 786 | |
| 787 unsigned GraphicsContext3D::getChannelBitsByFormat(GC3Denum format) | |
| 788 { | |
| 789 switch (format) { | |
| 790 case GraphicsContext3D::ALPHA: | |
| 791 return ChannelAlpha; | |
| 792 case GraphicsContext3D::LUMINANCE: | |
| 793 return ChannelRGB; | |
| 794 case GraphicsContext3D::LUMINANCE_ALPHA: | |
| 795 return ChannelRGBA; | |
| 796 case GraphicsContext3D::RGB: | |
| 797 case GraphicsContext3D::RGB565: | |
| 798 return ChannelRGB; | |
| 799 case GraphicsContext3D::RGBA: | |
| 800 case GraphicsContext3D::RGBA4: | |
| 801 case GraphicsContext3D::RGB5_A1: | |
| 802 return ChannelRGBA; | |
| 803 case GraphicsContext3D::DEPTH_COMPONENT16: | |
| 804 case GraphicsContext3D::DEPTH_COMPONENT: | |
| 805 return ChannelDepth; | |
| 806 case GraphicsContext3D::STENCIL_INDEX8: | |
| 807 return ChannelStencil; | |
| 808 case GraphicsContext3D::DEPTH_STENCIL: | |
| 809 return ChannelDepth | ChannelStencil; | |
| 810 default: | |
| 811 return 0; | |
| 812 } | |
| 813 } | |
| 814 | |
| 815 void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int
height, bool premultiplyAlpha, ImageBuffer* imageBuffer) | |
| 816 { | |
| 817 unsigned char* pixels = 0; | |
| 818 | |
| 819 const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap(); | |
| 820 const SkBitmap* readbackBitmap = 0; | |
| 821 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); | |
| 822 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { | |
| 823 // This is the fastest and most common case. We read back | |
| 824 // directly into the canvas's backing store. | |
| 825 readbackBitmap = canvasBitmap; | |
| 826 m_resizingBitmap.reset(); | |
| 827 } else { | |
| 828 // We need to allocate a temporary bitmap for reading back the | |
| 829 // pixel data. We will then use Skia to rescale this bitmap to | |
| 830 // the size of the canvas's backing store. | |
| 831 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { | |
| 832 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, heigh
t); | |
| 833 if (!m_resizingBitmap.allocPixels()) | |
| 834 return; | |
| 835 } | |
| 836 readbackBitmap = &m_resizingBitmap; | |
| 837 } | |
| 838 | |
| 839 // Read back the frame buffer. | |
| 840 SkAutoLockPixels bitmapLock(*readbackBitmap); | |
| 841 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); | |
| 842 | |
| 843 m_impl->bindFramebuffer(FRAMEBUFFER, framebuffer); | |
| 844 readBackFramebuffer(pixels, width, height, ReadbackSkia, premultiplyAlpha ?
AlphaDoPremultiply : AlphaDoNothing); | |
| 845 flipVertically(pixels, width, height); | |
| 846 | |
| 847 readbackBitmap->notifyPixelsChanged(); | |
| 848 if (m_resizingBitmap.readyToDraw()) { | |
| 849 // We need to draw the resizing bitmap into the canvas's backing store. | |
| 850 SkCanvas canvas(*canvasBitmap); | |
| 851 SkRect dst; | |
| 852 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); | |
| 853 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); | |
| 854 } | |
| 855 } | |
| 856 | |
| 857 namespace { | |
| 858 | |
| 859 void splitStringHelper(const String& str, HashSet<String>& set) | |
| 860 { | |
| 861 Vector<String> substrings; | |
| 862 str.split(" ", substrings); | |
| 863 for (size_t i = 0; i < substrings.size(); ++i) | |
| 864 set.add(substrings[i]); | |
| 865 } | |
| 866 | |
| 867 String mapExtensionName(const String& name) | |
| 868 { | |
| 869 if (name == "GL_ANGLE_framebuffer_blit" | |
| 870 || name == "GL_ANGLE_framebuffer_multisample") | |
| 871 return "GL_CHROMIUM_framebuffer_multisample"; | |
| 872 return name; | |
| 873 } | |
| 874 | |
| 875 } // anonymous namespace | |
| 876 | |
| 877 void GraphicsContext3D::initializeExtensions() | |
| 878 { | |
| 879 if (m_initializedAvailableExtensions) | |
| 880 return; | |
| 881 | |
| 882 m_initializedAvailableExtensions = true; | |
| 883 bool success = m_impl->makeContextCurrent(); | |
| 884 ASSERT(success); | |
| 885 if (!success) | |
| 886 return; | |
| 887 | |
| 888 String extensionsString = m_impl->getString(GraphicsContext3D::EXTENSIONS); | |
| 889 splitStringHelper(extensionsString, m_enabledExtensions); | |
| 890 | |
| 891 String requestableExtensionsString = m_impl->getRequestableExtensionsCHROMIU
M(); | |
| 892 splitStringHelper(requestableExtensionsString, m_requestableExtensions); | |
| 893 } | |
| 894 | |
| 895 | |
| 896 bool GraphicsContext3D::supportsExtension(const String& name) | |
| 897 { | |
| 898 initializeExtensions(); | |
| 899 String mappedName = mapExtensionName(name); | |
| 900 return m_enabledExtensions.contains(mappedName) || m_requestableExtensions.c
ontains(mappedName); | |
| 901 } | |
| 902 | |
| 903 bool GraphicsContext3D::ensureExtensionEnabled(const String& name) | |
| 904 { | |
| 905 initializeExtensions(); | |
| 906 | |
| 907 String mappedName = mapExtensionName(name); | |
| 908 if (m_enabledExtensions.contains(mappedName)) | |
| 909 return true; | |
| 910 | |
| 911 if (m_requestableExtensions.contains(mappedName)) { | |
| 912 m_impl->requestExtensionCHROMIUM(mappedName.ascii().data()); | |
| 913 m_enabledExtensions.clear(); | |
| 914 m_requestableExtensions.clear(); | |
| 915 m_initializedAvailableExtensions = false; | |
| 916 } | |
| 917 | |
| 918 initializeExtensions(); | |
| 919 fprintf(stderr, "m_enabledExtensions.contains(%s) == %d\n", mappedName.ascii
().data(), m_enabledExtensions.contains(mappedName)); | |
| 920 return m_enabledExtensions.contains(mappedName); | |
| 921 } | |
| 922 | |
| 923 bool GraphicsContext3D::isExtensionEnabled(const String& name) | |
| 924 { | |
| 925 initializeExtensions(); | |
| 926 String mappedName = mapExtensionName(name); | |
| 927 return m_enabledExtensions.contains(mappedName); | |
| 928 } | |
| 929 | |
| 930 void GraphicsContext3D::flipVertically(uint8_t* framebuffer, int width, int heig
ht) | |
| 931 { | |
| 932 m_scanline.resize(width * 4); | |
| 933 uint8* scanline = &m_scanline[0]; | |
| 934 unsigned rowBytes = width * 4; | |
| 935 unsigned count = height / 2; | |
| 936 for (unsigned i = 0; i < count; i++) { | |
| 937 uint8* rowA = framebuffer + i * rowBytes; | |
| 938 uint8* rowB = framebuffer + (height - i - 1) * rowBytes; | |
| 939 memcpy(scanline, rowB, rowBytes); | |
| 940 memcpy(rowB, rowA, rowBytes); | |
| 941 memcpy(rowA, scanline, rowBytes); | |
| 942 } | |
| 943 } | |
| 944 | |
| 945 } // namespace WebCore | |
| OLD | NEW |