summaryrefslogtreecommitdiffstats
path: root/WebCore/html/canvas/WebGLRenderingContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/canvas/WebGLRenderingContext.cpp')
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.cpp184
1 files changed, 104 insertions, 80 deletions
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index a82a4ac4..f567ac8 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -115,12 +115,12 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType);
m_implementationColorReadType = implementationColorReadType;
- int maxTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
- m_maxTextureSize = maxTextureSize;
- int maxCubeMapTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapTextureSize);
- m_maxCubeMapTextureSize = maxCubeMapTextureSize;
+ m_maxTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
+ m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
+ m_maxCubeMapTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
+ m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
if (!isGLES2Compliant()) {
createFallbackBlackTextures1x1();
@@ -141,17 +141,23 @@ void WebGLRenderingContext::markContextChanged()
RenderBox* renderBox = canvas()->renderBox();
if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
renderBox->layer()->rendererContentChanged();
- else {
#endif
- if (!m_markedCanvasDirty) {
- // Make sure the canvas's image buffer is allocated.
- canvas()->buffer();
- canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
- m_markedCanvasDirty = true;
- }
-#if USE(ACCELERATED_COMPOSITING)
+ if (!m_markedCanvasDirty) {
+ // Make sure the canvas's image buffer is allocated.
+ canvas()->buffer();
+ canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
+ m_markedCanvasDirty = true;
}
-#endif
+}
+
+bool WebGLRenderingContext::paintRenderingResultsToCanvas()
+{
+ if (m_markedCanvasDirty) {
+ m_markedCanvasDirty = false;
+ m_context->paintRenderingResultsToCanvas(this);
+ return true;
+ }
+ return false;
}
void WebGLRenderingContext::beginPaint()
@@ -293,17 +299,20 @@ void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* text
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
- if (target == GraphicsContext3D::TEXTURE_2D)
+ int maxLevel = 0;
+ if (target == GraphicsContext3D::TEXTURE_2D) {
m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
- else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
+ maxLevel = m_maxTextureLevel;
+ } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
- else {
+ maxLevel = m_maxCubeMapTextureLevel;
+ } else {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return;
}
m_context->bindTexture(target, texture);
if (!isGLES2Compliant() && texture)
- texture->setTarget(target);
+ texture->setTarget(target, maxLevel);
cleanupAfterGraphicsCall(false);
}
@@ -349,22 +358,11 @@ void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned lon
void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!isGLES2Compliant()) {
- if (!validateBufferDataUsage(usage))
- return;
- }
- if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
- if (!m_boundElementArrayBuffer->associateBufferData(size)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
- } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
- if (!m_boundArrayBuffer->associateBufferData(size)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
- } else {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (!buffer->associateBufferData(size)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
@@ -372,25 +370,29 @@ void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec)
+void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!isGLES2Compliant()) {
- if (!validateBufferDataUsage(usage))
- return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
}
- if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
- if (!m_boundElementArrayBuffer->associateBufferData(data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
- } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
- if (!m_boundArrayBuffer->associateBufferData(data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
- } else {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+
+ m_context->bufferData(target, data, usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
@@ -398,21 +400,29 @@ void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* da
cleanupAfterGraphicsCall(false);
}
+void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBuffer* data, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ m_context->bufferSubData(target, offset, data);
+ cleanupAfterGraphicsCall(false);
+}
+
void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
- if (!m_boundElementArrayBuffer->associateBufferSubData(offset, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
- } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
- if (!m_boundArrayBuffer->associateBufferSubData(offset, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
- return;
- }
- } else {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
@@ -507,10 +517,8 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
// FIXME: if the framebuffer is not complete, none of the below should be executed.
WebGLTexture* tex = getTextureBinding(target);
if (!isGLES2Compliant()) {
- if (tex && !level) // only for level 0
- tex->setSize(target, width, height);
if (tex)
- tex->setInternalFormat(internalformat);
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
}
if (m_framebufferBinding && tex)
m_framebufferBinding->onAttachedObjectChange(tex);
@@ -1082,18 +1090,22 @@ void WebGLRenderingContext::frontFace(unsigned long mode)
void WebGLRenderingContext::generateMipmap(unsigned long target)
{
+ RefPtr<WebGLTexture> tex;
if (!isGLES2Compliant()) {
- RefPtr<WebGLTexture> tex = 0;
if (target == GraphicsContext3D::TEXTURE_2D)
tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
- if (tex && tex->isNPOT()) {
+ if (tex && !tex->canGenerateMipmaps()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
}
m_context->generateMipmap(target);
+ if (!isGLES2Compliant()) {
+ if (tex)
+ tex->generateMipmapLevelInfo();
+ }
cleanupAfterGraphicsCall(false);
}
@@ -1337,7 +1349,8 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC
case GraphicsContext3D::MAX_VIEWPORT_DIMS:
return getWebGLIntArrayParameter(pname);
case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS:
- return getLongParameter(pname);
+ // WebGL 1.0 specifies that there are no compressed texture formats.
+ return WebGLGetInfo(static_cast<long>(0));
case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
// FIXME: should we always return 0 for this?
return getLongParameter(pname);
@@ -2082,10 +2095,8 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
border, format, type, pixels);
WebGLTexture* tex = getTextureBinding(target);
if (!isGLES2Compliant()) {
- if (tex && !level) // only for level 0
- tex->setSize(target, width, height);
if (tex)
- tex->setInternalFormat(internalformat);
+ tex->setLevelInfo(target, level, internalformat, width, height, type);
}
if (m_framebufferBinding && tex)
m_framebufferBinding->onAttachedObjectChange(tex);
@@ -3369,9 +3380,6 @@ bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long
if (!validateTexFuncFormatAndType(format, type))
return false;
- if (isGLES2Compliant())
- return true;
-
if (width < 0 || height < 0 || level < 0) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return false;
@@ -3379,7 +3387,7 @@ bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long
switch (target) {
case GraphicsContext3D::TEXTURE_2D:
- if (width > m_maxTextureSize || height > m_maxTextureSize) {
+ if (width > m_maxTextureSize || height > m_maxTextureSize || level > m_maxTextureLevel) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return false;
}
@@ -3390,7 +3398,7 @@ bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (width != height || width > m_maxCubeMapTextureSize) {
+ if (width != height || width > m_maxCubeMapTextureSize || level > m_maxCubeMapTextureLevel) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return false;
}
@@ -3592,16 +3600,32 @@ bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLo
return true;
}
-bool WebGLRenderingContext::validateBufferDataUsage(unsigned long usage)
+WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(unsigned long target, unsigned long usage)
{
+ WebGLBuffer* buffer = 0;
+ switch (target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ buffer = m_boundElementArrayBuffer.get();
+ break;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ buffer = m_boundArrayBuffer.get();
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ if (!buffer) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return 0;
+ }
switch (usage) {
case GraphicsContext3D::STREAM_DRAW:
case GraphicsContext3D::STATIC_DRAW:
case GraphicsContext3D::DYNAMIC_DRAW:
- return true;
+ return buffer;
}
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
- return false;
+ return 0;
}
void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedSize, float v0, float v1, float v2, float v3)