summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp')
-rw-r--r--Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp348
1 files changed, 348 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
new file mode 100644
index 0000000..9d1298f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2010, Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+
+#include "SharedGraphicsContext3D.h"
+
+#include "AffineTransform.h"
+#include "Color.h"
+#include "Extensions3D.h"
+#include "FloatRect.h"
+#include "IntSize.h"
+#include "SolidFillShader.h"
+#include "TexShader.h"
+
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// static
+PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow* hostWindow)
+{
+ GraphicsContext3D::Attributes attr;
+ attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts.
+ RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow);
+ if (!context)
+ return 0;
+ OwnPtr<SolidFillShader> solidFillShader = SolidFillShader::create(context.get());
+ if (!solidFillShader)
+ return 0;
+ OwnPtr<TexShader> texShader = TexShader::create(context.get());
+ if (!texShader)
+ return 0;
+ return adoptRef(new SharedGraphicsContext3D(context.release(), solidFillShader.release(), texShader.release()));
+}
+
+SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<SolidFillShader> solidFillShader, PassOwnPtr<TexShader> texShader)
+ : m_context(context)
+ , m_bgraSupported(false)
+ , m_quadVertices(0)
+ , m_solidFillShader(solidFillShader)
+ , m_texShader(texShader)
+{
+ allContexts()->add(this);
+ Extensions3D* extensions = m_context->getExtensions();
+ m_bgraSupported = extensions->supports("GL_EXT_texture_format_BGRA8888") && extensions->supports("GL_EXT_read_format_bgra");
+ if (m_bgraSupported) {
+ extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");
+ extensions->ensureEnabled("GL_EXT_read_format_bgra");
+ }
+}
+
+SharedGraphicsContext3D::~SharedGraphicsContext3D()
+{
+ m_context->deleteBuffer(m_quadVertices);
+ allContexts()->remove(this);
+}
+
+void SharedGraphicsContext3D::makeContextCurrent()
+{
+ m_context->makeContextCurrent();
+}
+
+void SharedGraphicsContext3D::scissor(const FloatRect& rect)
+{
+ m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void SharedGraphicsContext3D::enable(GC3Denum capacity)
+{
+ m_context->enable(capacity);
+}
+
+void SharedGraphicsContext3D::disable(GC3Denum capacity)
+{
+ m_context->disable(capacity);
+}
+
+void SharedGraphicsContext3D::clearColor(const Color& color)
+{
+ float rgba[4];
+ color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
+ m_context->clearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
+}
+
+void SharedGraphicsContext3D::clear(GC3Dbitfield mask)
+{
+ m_context->clear(mask);
+}
+
+void SharedGraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
+{
+ m_context->drawArrays(mode, first, count);
+}
+
+GC3Denum SharedGraphicsContext3D::getError()
+{
+ return m_context->getError();
+}
+
+void SharedGraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
+{
+ m_context->getIntegerv(pname, value);
+}
+
+void SharedGraphicsContext3D::flush()
+{
+ m_context->flush();
+}
+
+Platform3DObject SharedGraphicsContext3D::createFramebuffer()
+{
+ return m_context->createFramebuffer();
+}
+
+Platform3DObject SharedGraphicsContext3D::createTexture()
+{
+ return m_context->createTexture();
+}
+
+void SharedGraphicsContext3D::deleteFramebuffer(Platform3DObject framebuffer)
+{
+ m_context->deleteFramebuffer(framebuffer);
+}
+
+void SharedGraphicsContext3D::deleteTexture(Platform3DObject texture)
+{
+ m_context->deleteTexture(texture);
+}
+
+void SharedGraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level)
+{
+ m_context->framebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void SharedGraphicsContext3D::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
+{
+ m_context->texParameteri(target, pname, param);
+}
+
+bool SharedGraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
+{
+ if (!pixels)
+ return m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border, format, type);
+ return m_context->texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+void SharedGraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
+{
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void SharedGraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
+{
+ m_context->readPixels(x, y, width, height, format, type, data);
+}
+
+bool SharedGraphicsContext3D::supportsBGRA()
+{
+ return m_bgraSupported;
+}
+
+Texture* SharedGraphicsContext3D::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height)
+{
+ RefPtr<Texture> texture = m_textures.get(ptr);
+ if (texture)
+ return texture.get();
+
+ texture = Texture::create(m_context.get(), format, width, height);
+ Texture* t = texture.get();
+ m_textures.set(ptr, texture);
+ return t;
+}
+
+Texture* SharedGraphicsContext3D::getTexture(NativeImagePtr ptr)
+{
+ RefPtr<Texture> texture = m_textures.get(ptr);
+ return texture ? texture.get() : 0;
+}
+
+void SharedGraphicsContext3D::removeTextureFor(NativeImagePtr ptr)
+{
+ TextureHashMap::iterator it = m_textures.find(ptr);
+ if (it != m_textures.end())
+ m_textures.remove(it);
+}
+
+// static
+void SharedGraphicsContext3D::removeTexturesFor(NativeImagePtr ptr)
+{
+ for (HashSet<SharedGraphicsContext3D*>::iterator it = allContexts()->begin(); it != allContexts()->end(); ++it)
+ (*it)->removeTextureFor(ptr);
+}
+
+// static
+HashSet<SharedGraphicsContext3D*>* SharedGraphicsContext3D::allContexts()
+{
+ DEFINE_STATIC_LOCAL(HashSet<SharedGraphicsContext3D*>, allContextsSet, ());
+ return &allContextsSet;
+}
+
+
+PassRefPtr<Texture> SharedGraphicsContext3D::createTexture(Texture::Format format, int width, int height)
+{
+ return Texture::create(m_context.get(), format, width, height);
+}
+
+void SharedGraphicsContext3D::applyCompositeOperator(CompositeOperator op)
+{
+ switch (op) {
+ case CompositeClear:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ZERO);
+ break;
+ case CompositeCopy:
+ m_context->disable(GraphicsContext3D::BLEND);
+ break;
+ case CompositeSourceOver:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositeSourceIn:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ZERO);
+ break;
+ case CompositeSourceOut:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ZERO);
+ break;
+ case CompositeSourceAtop:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositeDestinationOver:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE);
+ break;
+ case CompositeDestinationIn:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::SRC_ALPHA);
+ break;
+ case CompositeDestinationOut:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositeDestinationAtop:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::SRC_ALPHA);
+ break;
+ case CompositeXOR:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositePlusDarker:
+ case CompositeHighlight:
+ // unsupported
+ m_context->disable(GraphicsContext3D::BLEND);
+ break;
+ case CompositePlusLighter:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE);
+ break;
+ }
+}
+
+void SharedGraphicsContext3D::useQuadVertices()
+{
+ if (!m_quadVertices) {
+ float vertices[] = { 0.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f };
+ m_quadVertices = m_context->createBuffer();
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
+ } else {
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
+ }
+}
+
+void SharedGraphicsContext3D::setActiveTexture(GC3Denum textureUnit)
+{
+ m_context->activeTexture(textureUnit);
+}
+
+void SharedGraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
+{
+ m_context->bindTexture(target, texture);
+}
+
+void SharedGraphicsContext3D::useFillSolidProgram(const AffineTransform& transform, const Color& color)
+{
+ m_solidFillShader->use(transform, color);
+}
+
+void SharedGraphicsContext3D::useTextureProgram(const AffineTransform& transform, const AffineTransform& texTransform, float alpha)
+{
+ m_texShader->use(transform, texTransform, 0, alpha);
+}
+
+void SharedGraphicsContext3D::bindFramebuffer(Platform3DObject framebuffer)
+{
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer);
+}
+
+void SharedGraphicsContext3D::setViewport(const IntSize& size)
+{
+ m_context->viewport(0, 0, size.width(), size.height());
+}
+
+bool SharedGraphicsContext3D::paintsIntoCanvasBuffer() const
+{
+ return m_context->paintsIntoCanvasBuffer();
+}
+
+} // namespace WebCore
+
+#endif