summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp')
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp742
1 files changed, 183 insertions, 559 deletions
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
index 05b884bd5..7464d047e 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
@@ -22,6 +22,10 @@
#include "config.h"
#include "TextureMapperGL.h"
+#if USE(TEXTURE_MAPPER_GL)
+
+#include "BitmapTextureGL.h"
+#include "BitmapTexturePool.h"
#include "Extensions3D.h"
#include "FilterOperations.h"
#include "GraphicsContext.h"
@@ -31,9 +35,10 @@
#include "TextureMapperShaderProgram.h"
#include "Timer.h"
#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/TemporaryChange.h>
+#include <wtf/SetForScope.h>
#if USE(CAIRO)
#include "CairoUtilities.h"
@@ -42,191 +47,84 @@
#include <wtf/text/CString.h>
#endif
-#if !USE(TEXMAP_OPENGL_ES_2)
-// FIXME: Move to Extensions3D.h.
-#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
-#define GL_UNPACK_ROW_LENGTH 0x0CF2
-#define GL_UNPACK_SKIP_PIXELS 0x0CF4
-#define GL_UNPACK_SKIP_ROWS 0x0CF3
-#endif
-
-#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
-
namespace WebCore {
-struct TextureMapperGLData {
+
+class TextureMapperGLData {
WTF_MAKE_FAST_ALLOCATED;
public:
- struct SharedGLData : public RefCounted<SharedGLData> {
+ explicit TextureMapperGLData(GraphicsContext3D&);
+ ~TextureMapperGLData();
- typedef HashMap<PlatformGraphicsContext3D, SharedGLData*> GLContextDataMap;
- static GLContextDataMap& glContextDataMap()
- {
- static GLContextDataMap map;
- return map;
- }
+ void initializeStencil();
+ Platform3DObject getStaticVBO(GC3Denum target, GC3Dsizeiptr, const void* data);
+ Ref<TextureMapperShaderProgram> getShaderProgram(TextureMapperShaderProgram::Options);
+
+ TransformationMatrix projectionMatrix;
+ TextureMapper::PaintFlags PaintFlags { 0 };
+ GC3Dint previousProgram { 0 };
+ GC3Dint targetFrameBuffer { 0 };
+ bool didModifyStencil { false };
+ GC3Dint previousScissorState { 0 };
+ GC3Dint previousDepthState { 0 };
+ GC3Dint viewport[4] { 0, };
+ GC3Dint previousScissor[4] { 0, };
+ RefPtr<BitmapTexture> currentSurface;
+ const BitmapTextureGL::FilterInfo* filterInfo { nullptr };
- static PassRefPtr<SharedGLData> currentSharedGLData(GraphicsContext3D* context)
+private:
+ class SharedGLData : public RefCounted<SharedGLData> {
+ public:
+ static Ref<SharedGLData> currentSharedGLData(GraphicsContext3D& context)
{
- GLContextDataMap::iterator it = glContextDataMap().find(context->platformGraphicsContext3D());
- if (it != glContextDataMap().end())
- return it->value;
+ auto it = contextDataMap().find(context.platformGraphicsContext3D());
+ if (it != contextDataMap().end())
+ return *it->value;
- return adoptRef(new SharedGLData(context));
+ Ref<SharedGLData> data = adoptRef(*new SharedGLData(context));
+ contextDataMap().add(context.platformGraphicsContext3D(), data.ptr());
+ return data;
}
- PassRefPtr<TextureMapperShaderProgram> getShaderProgram(TextureMapperShaderProgram::Options options)
+ ~SharedGLData()
{
- HashMap<TextureMapperShaderProgram::Options, RefPtr<TextureMapperShaderProgram> >::AddResult result = m_programs.add(options, nullptr);
- if (result.isNewEntry)
- result.iterator->value = TextureMapperShaderProgram::create(m_context, options);
-
- return result.iterator->value;
+ ASSERT(std::any_of(contextDataMap().begin(), contextDataMap().end(),
+ [this](auto& entry) { return entry.value == this; }));
+ contextDataMap().removeIf([this](auto& entry) { return entry.value == this; });
}
- HashMap<TextureMapperShaderProgram::Options, RefPtr<TextureMapperShaderProgram> > m_programs;
- RefPtr<GraphicsContext3D> m_context;
+ private:
+ friend class TextureMapperGLData;
- explicit SharedGLData(GraphicsContext3D* context)
- : m_context(context)
+ using GLContextDataMap = HashMap<PlatformGraphicsContext3D, SharedGLData*>;
+ static GLContextDataMap& contextDataMap()
{
- glContextDataMap().add(context->platformGraphicsContext3D(), this);
+ static NeverDestroyed<GLContextDataMap> map;
+ return map;
}
- ~SharedGLData()
+ explicit SharedGLData(GraphicsContext3D& context)
{
- GLContextDataMap::const_iterator end = glContextDataMap().end();
- GLContextDataMap::iterator it;
- for (it = glContextDataMap().begin(); it != end; ++it) {
- if (it->value == this)
- break;
- }
-
- ASSERT(it != end);
- glContextDataMap().remove(it);
+ contextDataMap().add(context.platformGraphicsContext3D(), this);
}
- };
-
- SharedGLData& sharedGLData() const
- {
- return *sharedData;
- }
- void initializeStencil();
-
- explicit TextureMapperGLData(GraphicsContext3D* context)
- : context(context)
- , PaintFlags(0)
- , previousProgram(0)
- , targetFrameBuffer(0)
- , didModifyStencil(false)
- , previousScissorState(0)
- , previousDepthState(0)
- , sharedData(TextureMapperGLData::SharedGLData::currentSharedGLData(this->context))
-#if ENABLE(CSS_FILTERS)
- , filterInfo(0)
-#endif
- { }
-
- ~TextureMapperGLData();
- Platform3DObject getStaticVBO(GC3Denum target, GC3Dsizeiptr, const void* data);
+ HashMap<TextureMapperShaderProgram::Options, RefPtr<TextureMapperShaderProgram>> m_programs;
+ };
- GraphicsContext3D* context;
- TransformationMatrix projectionMatrix;
- TextureMapper::PaintFlags PaintFlags;
- GC3Dint previousProgram;
- GC3Dint targetFrameBuffer;
- bool didModifyStencil;
- GC3Dint previousScissorState;
- GC3Dint previousDepthState;
- GC3Dint viewport[4];
- GC3Dint previousScissor[4];
- RefPtr<SharedGLData> sharedData;
- RefPtr<BitmapTexture> currentSurface;
- HashMap<const void*, Platform3DObject> vbos;
-#if ENABLE(CSS_FILTERS)
- const BitmapTextureGL::FilterInfo* filterInfo;
-#endif
+ GraphicsContext3D& m_context;
+ Ref<SharedGLData> m_sharedGLData;
+ HashMap<const void*, Platform3DObject> m_vbos;
};
-Platform3DObject TextureMapperGLData::getStaticVBO(GC3Denum target, GC3Dsizeiptr size, const void* data)
+TextureMapperGLData::TextureMapperGLData(GraphicsContext3D& context)
+ : m_context(context)
+ , m_sharedGLData(SharedGLData::currentSharedGLData(m_context))
{
- HashMap<const void*, Platform3DObject>::AddResult result = vbos.add(data, 0);
- if (result.isNewEntry) {
- Platform3DObject vbo = context->createBuffer();
- context->bindBuffer(target, vbo);
- context->bufferData(target, size, data, GraphicsContext3D::STATIC_DRAW);
- result.iterator->value = vbo;
- }
-
- return result.iterator->value;
}
TextureMapperGLData::~TextureMapperGLData()
{
- HashMap<const void*, Platform3DObject>::iterator end = vbos.end();
- for (HashMap<const void*, Platform3DObject>::iterator it = vbos.begin(); it != end; ++it)
- context->deleteBuffer(it->value);
-}
-
-void TextureMapperGL::ClipStack::reset(const IntRect& rect, TextureMapperGL::ClipStack::YAxisMode mode)
-{
- clipStack.clear();
- size = rect.size();
- yAxisMode = mode;
- clipState = TextureMapperGL::ClipState(rect);
- clipStateDirty = true;
-}
-
-void TextureMapperGL::ClipStack::intersect(const IntRect& rect)
-{
- clipState.scissorBox.intersect(rect);
- clipStateDirty = true;
-}
-
-void TextureMapperGL::ClipStack::setStencilIndex(int stencilIndex)
-{
- clipState.stencilIndex = stencilIndex;
- clipStateDirty = true;
-}
-
-void TextureMapperGL::ClipStack::push()
-{
- clipStack.append(clipState);
- clipStateDirty = true;
-}
-
-void TextureMapperGL::ClipStack::pop()
-{
- if (clipStack.isEmpty())
- return;
- clipState = clipStack.last();
- clipStack.removeLast();
- clipStateDirty = true;
-}
-
-void TextureMapperGL::ClipStack::apply(GraphicsContext3D* context)
-{
- if (clipState.scissorBox.isEmpty())
- return;
-
- context->scissor(clipState.scissorBox.x(),
- (yAxisMode == InvertedYAxis) ? size.height() - clipState.scissorBox.maxY() : clipState.scissorBox.y(),
- clipState.scissorBox.width(), clipState.scissorBox.height());
- context->stencilOp(GraphicsContext3D::KEEP, GraphicsContext3D::KEEP, GraphicsContext3D::KEEP);
- context->stencilFunc(GraphicsContext3D::EQUAL, clipState.stencilIndex - 1, clipState.stencilIndex - 1);
- if (clipState.stencilIndex == 1)
- context->disable(GraphicsContext3D::STENCIL_TEST);
- else
- context->enable(GraphicsContext3D::STENCIL_TEST);
-}
-
-void TextureMapperGL::ClipStack::applyIfNeeded(GraphicsContext3D* context)
-{
- if (!clipStateDirty)
- return;
-
- clipStateDirty = false;
- apply(context);
+ for (auto& entry : m_vbos)
+ m_context.deleteBuffer(entry.value);
}
void TextureMapperGLData::initializeStencil()
@@ -239,30 +137,45 @@ void TextureMapperGLData::initializeStencil()
if (didModifyStencil)
return;
- context->clearStencil(0);
- context->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
+ m_context.clearStencil(0);
+ m_context.clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
didModifyStencil = true;
}
-BitmapTextureGL* toBitmapTextureGL(BitmapTexture* texture)
+Platform3DObject TextureMapperGLData::getStaticVBO(GC3Denum target, GC3Dsizeiptr size, const void* data)
{
- if (!texture || !texture->isBackedByOpenGL())
- return 0;
+ auto addResult = m_vbos.ensure(data,
+ [this, target, size, data] {
+ Platform3DObject vbo = m_context.createBuffer();
+ m_context.bindBuffer(target, vbo);
+ m_context.bufferData(target, size, data, GraphicsContext3D::STATIC_DRAW);
+ return vbo;
+ });
+ return addResult.iterator->value;
+}
- return static_cast<BitmapTextureGL*>(texture);
+Ref<TextureMapperShaderProgram> TextureMapperGLData::getShaderProgram(TextureMapperShaderProgram::Options options)
+{
+ auto addResult = m_sharedGLData->m_programs.ensure(options,
+ [this, options] { return TextureMapperShaderProgram::create(Ref<GraphicsContext3D>(m_context), options); });
+ return *addResult.iterator->value;
}
TextureMapperGL::TextureMapperGL()
- : TextureMapper(OpenGLMode)
- , m_enableEdgeDistanceAntialiasing(false)
+ : m_enableEdgeDistanceAntialiasing(false)
{
m_context3D = GraphicsContext3D::createForCurrentGLContext();
- m_data = new TextureMapperGLData(m_context3D.get());
+ ASSERT(m_context3D);
+
+ m_data = new TextureMapperGLData(*m_context3D);
+#if USE(TEXTURE_MAPPER_GL)
+ m_texturePool = std::make_unique<BitmapTexturePool>(m_context3D.copyRef());
+#endif
}
-TextureMapperGL::ClipStack& TextureMapperGL::clipStack()
+ClipStack& TextureMapperGL::clipStack()
{
- return data().currentSurface ? toBitmapTextureGL(data().currentSurface.get())->m_clipStack : m_clipStack;
+ return data().currentSurface ? toBitmapTextureGL(data().currentSurface.get())->clipStack() : m_clipStack;
}
void TextureMapperGL::beginPainting(PaintFlags flags)
@@ -276,7 +189,7 @@ void TextureMapperGL::beginPainting(PaintFlags flags)
m_context3D->depthMask(0);
m_context3D->getIntegerv(GraphicsContext3D::VIEWPORT, data().viewport);
m_context3D->getIntegerv(GraphicsContext3D::SCISSOR_BOX, data().previousScissor);
- m_clipStack.reset(IntRect(0, 0, data().viewport[2], data().viewport[3]), ClipStack::InvertedYAxis);
+ m_clipStack.reset(IntRect(0, 0, data().viewport[2], data().viewport[3]), flags & PaintingMirrored ? ClipStack::YAxisMode::Default : ClipStack::YAxisMode::Inverted);
m_context3D->getIntegerv(GraphicsContext3D::FRAMEBUFFER_BINDING, &data().targetFrameBuffer);
data().PaintFlags = flags;
bindSurface(0);
@@ -308,7 +221,7 @@ void TextureMapperGL::drawBorder(const Color& color, float width, const FloatRec
if (clipStack().isCurrentScissorBoxEmpty())
return;
- RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().getShaderProgram(TextureMapperShaderProgram::SolidColor);
+ Ref<TextureMapperShaderProgram> program = data().getShaderProgram(TextureMapperShaderProgram::SolidColor);
m_context3D->useProgram(program->programID());
float r, g, b, a;
@@ -316,7 +229,7 @@ void TextureMapperGL::drawBorder(const Color& color, float width, const FloatRec
m_context3D->uniform4f(program->colorLocation(), r, g, b, a);
m_context3D->lineWidth(width);
- draw(targetRect, modelViewMatrix, program.get(), GraphicsContext3D::LINE_LOOP, color.hasAlpha() ? ShouldBlend : 0);
+ draw(targetRect, modelViewMatrix, program.get(), GraphicsContext3D::LINE_LOOP, !color.isOpaque() ? ShouldBlend : 0);
}
// FIXME: drawNumber() should save a number texture-atlas and re-use whenever possible.
@@ -333,9 +246,15 @@ void TextureMapperGL::drawNumber(int number, const Color& color, const FloatPoin
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_t* cr = cairo_create(surface);
- float r, g, b, a;
- color.getRGBA(r, g, b, a);
- cairo_set_source_rgba(cr, b, g, r, a); // Since we won't swap R+B when uploading a texture, paint with the swapped R+B color.
+ // Since we won't swap R+B when uploading a texture, paint with the swapped R+B color.
+ if (color.isExtended())
+ cairo_set_source_rgba(cr, color.asExtended().blue(), color.asExtended().green(), color.asExtended().red(), color.asExtended().alpha());
+ else {
+ float r, g, b, a;
+ color.getRGBA(r, g, b, a);
+ cairo_set_source_rgba(cr, b, g, r, a);
+ }
+
cairo_rectangle(cr, 0, 0, width, height);
cairo_fill(cr);
@@ -367,8 +286,6 @@ void TextureMapperGL::drawNumber(int number, const Color& color, const FloatPoin
#endif
}
-#if ENABLE(CSS_FILTERS)
-
static TextureMapperShaderProgram::Options optionsForFilterType(FilterOperation::OperationType type, unsigned pass)
{
switch (type) {
@@ -399,27 +316,6 @@ static TextureMapperShaderProgram::Options optionsForFilterType(FilterOperation:
}
}
-static unsigned getPassesRequiredForFilter(FilterOperation::OperationType type)
-{
- switch (type) {
- case FilterOperation::GRAYSCALE:
- case FilterOperation::SEPIA:
- case FilterOperation::SATURATE:
- case FilterOperation::HUE_ROTATE:
- case FilterOperation::INVERT:
- case FilterOperation::BRIGHTNESS:
- case FilterOperation::CONTRAST:
- case FilterOperation::OPACITY:
- return 1;
- case FilterOperation::BLUR:
- case FilterOperation::DROP_SHADOW:
- // We use two-passes (vertical+horizontal) for blur and drop-shadow.
- return 2;
- default:
- return 0;
- }
-}
-
// Create a normal distribution of 21 values between -2 and 2.
static const unsigned GaussianKernelHalfWidth = 11;
static const float GaussianKernelStep = 0.2;
@@ -453,23 +349,23 @@ static float* gaussianKernel()
return kernel;
}
-static void prepareFilterProgram(TextureMapperShaderProgram* program, const FilterOperation& operation, unsigned pass, const IntSize& size, GC3Duint contentTexture)
+static void prepareFilterProgram(TextureMapperShaderProgram& program, const FilterOperation& operation, unsigned pass, const IntSize& size, GC3Duint contentTexture)
{
- RefPtr<GraphicsContext3D> context = program->context();
- context->useProgram(program->programID());
+ Ref<GraphicsContext3D> context = program.context();
+ context->useProgram(program.programID());
switch (operation.type()) {
case FilterOperation::GRAYSCALE:
case FilterOperation::SEPIA:
case FilterOperation::SATURATE:
case FilterOperation::HUE_ROTATE:
- context->uniform1f(program->filterAmountLocation(), static_cast<const BasicColorMatrixFilterOperation&>(operation).amount());
+ context->uniform1f(program.filterAmountLocation(), static_cast<const BasicColorMatrixFilterOperation&>(operation).amount());
break;
case FilterOperation::INVERT:
case FilterOperation::BRIGHTNESS:
case FilterOperation::CONTRAST:
case FilterOperation::OPACITY:
- context->uniform1f(program->filterAmountLocation(), static_cast<const BasicComponentTransferFilterOperation&>(operation).amount());
+ context->uniform1f(program.filterAmountLocation(), static_cast<const BasicComponentTransferFilterOperation&>(operation).amount());
break;
case FilterOperation::BLUR: {
const BlurFilterOperation& blur = static_cast<const BlurFilterOperation&>(operation);
@@ -481,29 +377,29 @@ static void prepareFilterProgram(TextureMapperShaderProgram* program, const Filt
else
radius.setWidth(floatValueForLength(blur.stdDeviation(), size.width()) / size.width());
- context->uniform2f(program->blurRadiusLocation(), radius.width(), radius.height());
- context->uniform1fv(program->gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
+ context->uniform2f(program.blurRadiusLocation(), radius.width(), radius.height());
+ context->uniform1fv(program.gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
break;
}
case FilterOperation::DROP_SHADOW: {
const DropShadowFilterOperation& shadow = static_cast<const DropShadowFilterOperation&>(operation);
- context->uniform1fv(program->gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
+ context->uniform1fv(program.gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
switch (pass) {
case 0:
// First pass: horizontal alpha blur.
- context->uniform2f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.width()), 0);
- context->uniform2f(program->shadowOffsetLocation(), float(shadow.location().x()) / float(size.width()), float(shadow.location().y()) / float(size.height()));
+ context->uniform2f(program.blurRadiusLocation(), shadow.stdDeviation() / float(size.width()), 0);
+ context->uniform2f(program.shadowOffsetLocation(), float(shadow.location().x()) / float(size.width()), float(shadow.location().y()) / float(size.height()));
break;
case 1:
// Second pass: we need the shadow color and the content texture for compositing.
float r, g, b, a;
Color(premultipliedARGBFromColor(shadow.color())).getRGBA(r, g, b, a);
- context->uniform4f(program->colorLocation(), r, g, b, a);
- context->uniform2f(program->blurRadiusLocation(), 0, shadow.stdDeviation() / float(size.height()));
- context->uniform2f(program->shadowOffsetLocation(), 0, 0);
+ context->uniform4f(program.colorLocation(), r, g, b, a);
+ context->uniform2f(program.blurRadiusLocation(), 0, shadow.stdDeviation() / float(size.height()));
+ context->uniform2f(program.shadowOffsetLocation(), 0, 0);
context->activeTexture(GraphicsContext3D::TEXTURE1);
context->bindTexture(GraphicsContext3D::TEXTURE_2D, contentTexture);
- context->uniform1i(program->contentTextureLocation(), 1);
+ context->uniform1i(program.contentTextureLocation(), 1);
break;
}
break;
@@ -512,7 +408,6 @@ static void prepareFilterProgram(TextureMapperShaderProgram* program, const Filt
break;
}
}
-#endif
void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, unsigned exposedEdges)
{
@@ -523,13 +418,21 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect&
return;
const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture);
-#if ENABLE(CSS_FILTERS)
- TemporaryChange<const BitmapTextureGL::FilterInfo*> filterInfo(data().filterInfo, textureGL.filterInfo());
-#endif
+ SetForScope<const BitmapTextureGL::FilterInfo*> filterInfo(data().filterInfo, textureGL.filterInfo());
drawTexture(textureGL.id(), textureGL.isOpaque() ? 0 : ShouldBlend, textureGL.size(), targetRect, matrix, opacity, exposedEdges);
}
+static bool driverSupportsNPOTTextures(GraphicsContext3D& context)
+{
+ if (context.isGLES2Compliant()) {
+ static bool supportsNPOTTextures = context.getExtensions().supports("GL_OES_texture_npot");
+ return supportsNPOTTextures;
+ }
+
+ return true;
+}
+
void TextureMapperGL::drawTexture(Platform3DObject texture, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges)
{
bool useRect = flags & ShouldUseARBTextureRect;
@@ -546,8 +449,9 @@ void TextureMapperGL::drawTexture(Platform3DObject texture, Flags flags, const I
options |= TextureMapperShaderProgram::Antialiasing;
flags |= ShouldAntialias;
}
+ if (wrapMode() == RepeatWrap && !driverSupportsNPOTTextures(*m_context3D))
+ options |= TextureMapperShaderProgram::ManualRepeat;
-#if ENABLE(CSS_FILTERS)
RefPtr<FilterOperation> filter = data().filterInfo ? data().filterInfo->filter: 0;
GC3Duint filterContentTextureID = 0;
@@ -558,18 +462,14 @@ void TextureMapperGL::drawTexture(Platform3DObject texture, Flags flags, const I
if (filter->affectsOpacity())
flags |= ShouldBlend;
}
-#endif
if (useAntialiasing || opacity < 1)
flags |= ShouldBlend;
- RefPtr<TextureMapperShaderProgram> program;
- program = data().sharedGLData().getShaderProgram(options);
+ Ref<TextureMapperShaderProgram> program = data().getShaderProgram(options);
-#if ENABLE(CSS_FILTERS)
if (filter)
prepareFilterProgram(program.get(), *filter.get(), data().filterInfo->pass, textureSize, filterContentTextureID);
-#endif
drawTexturedQuadWithProgram(program.get(), texture, flags, textureSize, targetRect, modelViewMatrix, opacity);
}
@@ -583,7 +483,7 @@ void TextureMapperGL::drawSolidColor(const FloatRect& rect, const Transformation
flags |= ShouldBlend | ShouldAntialias;
}
- RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().getShaderProgram(options);
+ Ref<TextureMapperShaderProgram> program = data().getShaderProgram(options);
m_context3D->useProgram(program->programID());
float r, g, b, a;
@@ -595,7 +495,7 @@ void TextureMapperGL::drawSolidColor(const FloatRect& rect, const Transformation
draw(rect, matrix, program.get(), GraphicsContext3D::TRIANGLE_FAN, flags);
}
-void TextureMapperGL::drawEdgeTriangles(TextureMapperShaderProgram* program)
+void TextureMapperGL::drawEdgeTriangles(TextureMapperShaderProgram& program)
{
const GC3Dfloat left = 0;
const GC3Dfloat top = 0;
@@ -620,29 +520,29 @@ void TextureMapperGL::drawEdgeTriangles(TextureMapperShaderProgram* program)
Platform3DObject vbo = data().getStaticVBO(GraphicsContext3D::ARRAY_BUFFER, sizeof(GC3Dfloat) * 48, unitRectSideTriangles);
m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vbo);
- m_context3D->vertexAttribPointer(program->vertexLocation(), 4, GraphicsContext3D::FLOAT, false, 0, 0);
+ m_context3D->vertexAttribPointer(program.vertexLocation(), 4, GraphicsContext3D::FLOAT, false, 0, 0);
m_context3D->drawArrays(GraphicsContext3D::TRIANGLES, 0, 12);
m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
}
-void TextureMapperGL::drawUnitRect(TextureMapperShaderProgram* program, GC3Denum drawingMode)
+void TextureMapperGL::drawUnitRect(TextureMapperShaderProgram& program, GC3Denum drawingMode)
{
static const GC3Dfloat unitRect[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
Platform3DObject vbo = data().getStaticVBO(GraphicsContext3D::ARRAY_BUFFER, sizeof(GC3Dfloat) * 8, unitRect);
m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vbo);
- m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, 0);
+ m_context3D->vertexAttribPointer(program.vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, 0);
m_context3D->drawArrays(drawingMode, 0, 4);
m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
}
-void TextureMapperGL::draw(const FloatRect& rect, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram* shaderProgram, GC3Denum drawingMode, Flags flags)
+void TextureMapperGL::draw(const FloatRect& rect, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram& program, GC3Denum drawingMode, Flags flags)
{
- TransformationMatrix matrix =
- TransformationMatrix(modelViewMatrix).multiply(TransformationMatrix::rectToRect(FloatRect(0, 0, 1, 1), rect));
+ TransformationMatrix matrix(modelViewMatrix);
+ matrix.multiply(TransformationMatrix::rectToRect(FloatRect(0, 0, 1, 1), rect));
- m_context3D->enableVertexAttribArray(shaderProgram->vertexLocation());
- shaderProgram->setMatrix(shaderProgram->modelViewMatrixLocation(), matrix);
- shaderProgram->setMatrix(shaderProgram->projectionMatrixLocation(), data().projectionMatrix);
+ m_context3D->enableVertexAttribArray(program.vertexLocation());
+ program.setMatrix(program.modelViewMatrixLocation(), matrix);
+ program.setMatrix(program.projectionMatrixLocation(), data().projectionMatrix);
if (isInMaskMode()) {
m_context3D->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::SRC_ALPHA);
@@ -656,28 +556,40 @@ void TextureMapperGL::draw(const FloatRect& rect, const TransformationMatrix& mo
}
if (flags & ShouldAntialias)
- drawEdgeTriangles(shaderProgram);
+ drawEdgeTriangles(program);
else
- drawUnitRect(shaderProgram, drawingMode);
+ drawUnitRect(program, drawingMode);
- m_context3D->disableVertexAttribArray(shaderProgram->vertexLocation());
+ m_context3D->disableVertexAttribArray(program.vertexLocation());
m_context3D->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
m_context3D->enable(GraphicsContext3D::BLEND);
}
-void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* program, uint32_t texture, Flags flags, const IntSize& size, const FloatRect& rect, const TransformationMatrix& modelViewMatrix, float opacity)
+void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram& program, uint32_t texture, Flags flags, const IntSize& size, const FloatRect& rect, const TransformationMatrix& modelViewMatrix, float opacity)
{
- m_context3D->useProgram(program->programID());
+ m_context3D->useProgram(program.programID());
m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
GC3Denum target = flags & ShouldUseARBTextureRect ? GC3Denum(Extensions3D::TEXTURE_RECTANGLE_ARB) : GC3Denum(GraphicsContext3D::TEXTURE_2D);
m_context3D->bindTexture(target, texture);
- m_context3D->uniform1i(program->samplerLocation(), 0);
- if (wrapMode() == RepeatWrap) {
+ m_context3D->uniform1i(program.samplerLocation(), 0);
+ if (wrapMode() == RepeatWrap && driverSupportsNPOTTextures(*m_context3D)) {
m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::REPEAT);
m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::REPEAT);
}
TransformationMatrix patternTransform = this->patternTransform();
+ if (flags & ShouldRotateTexture90) {
+ patternTransform.rotate(-90);
+ patternTransform.translate(-1, 0);
+ }
+ if (flags & ShouldRotateTexture180) {
+ patternTransform.rotate(180);
+ patternTransform.translate(-1, -1);
+ }
+ if (flags & ShouldRotateTexture270) {
+ patternTransform.rotate(-270);
+ patternTransform.translate(0, -1);
+ }
if (flags & ShouldFlipTexture)
patternTransform.flipY();
if (flags & ShouldUseARBTextureRect)
@@ -685,8 +597,8 @@ void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* pr
if (flags & ShouldFlipTexture)
patternTransform.translate(0, -1);
- program->setMatrix(program->textureSpaceMatrixLocation(), patternTransform);
- m_context3D->uniform1f(program->opacityLocation(), opacity);
+ program.setMatrix(program.textureSpaceMatrixLocation(), patternTransform);
+ m_context3D->uniform1f(program.opacityLocation(), opacity);
if (opacity < 1)
flags |= ShouldBlend;
@@ -696,225 +608,17 @@ void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* pr
m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
}
-BitmapTextureGL::BitmapTextureGL(TextureMapperGL* textureMapper)
- : m_id(0)
- , m_fbo(0)
- , m_rbo(0)
- , m_depthBufferObject(0)
- , m_shouldClear(true)
- , m_context3D(textureMapper->graphicsContext3D())
-{
-}
-
-bool BitmapTextureGL::canReuseWith(const IntSize& contentsSize, Flags)
-{
- return contentsSize == m_textureSize;
-}
-
-#if OS(DARWIN)
-#define DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
-#else
-#define DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE GraphicsContext3D::UNSIGNED_BYTE
-#endif
-
-static void swizzleBGRAToRGBA(uint32_t* data, const IntRect& rect, int stride = 0)
-{
- stride = stride ? stride : rect.width();
- for (int y = rect.y(); y < rect.maxY(); ++y) {
- uint32_t* p = data + y * stride;
- for (int x = rect.x(); x < rect.maxX(); ++x)
- p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
- }
-}
-
-// If GL_EXT_texture_format_BGRA8888 is supported in the OpenGLES
-// internal and external formats need to be BGRA
-static bool driverSupportsExternalTextureBGRA(GraphicsContext3D* context)
-{
- if (context->isGLES2Compliant()) {
- static bool supportsExternalTextureBGRA = context->getExtensions()->supports("GL_EXT_texture_format_BGRA8888");
- return supportsExternalTextureBGRA;
- }
-
- return true;
-}
-
-static bool driverSupportsSubImage(GraphicsContext3D* context)
-{
- if (context->isGLES2Compliant()) {
- static bool supportsSubImage = context->getExtensions()->supports("GL_EXT_unpack_subimage");
- return supportsSubImage;
- }
-
- return true;
-}
-
-void BitmapTextureGL::didReset()
-{
- if (!m_id)
- m_id = m_context3D->createTexture();
-
- m_shouldClear = true;
- if (m_textureSize == contentSize())
- return;
-
-
- m_textureSize = contentSize();
- m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
- m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
- m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
- m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
- m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
-
- Platform3DObject internalFormat = GraphicsContext3D::RGBA;
- Platform3DObject externalFormat = GraphicsContext3D::BGRA;
- if (m_context3D->isGLES2Compliant()) {
- if (driverSupportsExternalTextureBGRA(m_context3D.get()))
- internalFormat = GraphicsContext3D::BGRA;
- else
- externalFormat = GraphicsContext3D::RGBA;
- }
-
- m_context3D->texImage2DDirect(GraphicsContext3D::TEXTURE_2D, 0, internalFormat, m_textureSize.width(), m_textureSize.height(), 0, externalFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, 0);
-}
-
-void BitmapTextureGL::updateContentsNoSwizzle(const void* srcData, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine, unsigned bytesPerPixel, Platform3DObject glFormat)
-{
- m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
- if (driverSupportsSubImage(m_context3D.get())) { // For ES drivers that don't support sub-images.
- // Use the OpenGL sub-image extension, now that we know it's available.
- m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, bytesPerLine / bytesPerPixel);
- m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, sourceOffset.y());
- m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, sourceOffset.x());
- }
-
- m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, srcData);
-
- if (driverSupportsSubImage(m_context3D.get())) { // For ES drivers that don't support sub-images.
- m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- }
-}
-
-void BitmapTextureGL::updateContents(const void* srcData, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag updateContentsFlag)
-{
- Platform3DObject glFormat = GraphicsContext3D::RGBA;
- m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
-
- const unsigned bytesPerPixel = 4;
- char* data = reinterpret_cast<char*>(const_cast<void*>(srcData));
- Vector<char> temporaryData;
- IntPoint adjustedSourceOffset = sourceOffset;
-
- // Texture upload requires subimage buffer if driver doesn't support subimage and we don't have full image upload.
- bool requireSubImageBuffer = !driverSupportsSubImage(m_context3D.get())
- && !(bytesPerLine == static_cast<int>(targetRect.width() * bytesPerPixel) && adjustedSourceOffset == IntPoint::zero());
-
- // prepare temporaryData if necessary
- if ((!driverSupportsExternalTextureBGRA(m_context3D.get()) && updateContentsFlag == UpdateCannotModifyOriginalImageData) || requireSubImageBuffer) {
- temporaryData.resize(targetRect.width() * targetRect.height() * bytesPerPixel);
- data = temporaryData.data();
- const char* bits = static_cast<const char*>(srcData);
- const char* src = bits + sourceOffset.y() * bytesPerLine + sourceOffset.x() * bytesPerPixel;
- char* dst = data;
- const int targetBytesPerLine = targetRect.width() * bytesPerPixel;
- for (int y = 0; y < targetRect.height(); ++y) {
- memcpy(dst, src, targetBytesPerLine);
- src += bytesPerLine;
- dst += targetBytesPerLine;
- }
-
- bytesPerLine = targetBytesPerLine;
- adjustedSourceOffset = IntPoint(0, 0);
- }
-
- if (driverSupportsExternalTextureBGRA(m_context3D.get()))
- glFormat = GraphicsContext3D::BGRA;
- else
- swizzleBGRAToRGBA(reinterpret_cast_ptr<uint32_t*>(data), IntRect(adjustedSourceOffset, targetRect.size()), bytesPerLine / bytesPerPixel);
-
- updateContentsNoSwizzle(data, targetRect, adjustedSourceOffset, bytesPerLine, bytesPerPixel, glFormat);
-}
-
-void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, const IntPoint& offset, UpdateContentsFlag updateContentsFlag)
-{
- if (!image)
- return;
- NativeImagePtr frameImage = image->nativeImageForCurrentFrame();
- if (!frameImage)
- return;
-
- int bytesPerLine;
- const char* imageData;
-
-#if USE(CAIRO)
- cairo_surface_t* surface = frameImage.get();
- imageData = reinterpret_cast<const char*>(cairo_image_surface_get_data(surface));
- bytesPerLine = cairo_image_surface_get_stride(surface);
-#endif
-
- updateContents(imageData, targetRect, offset, bytesPerLine, updateContentsFlag);
-}
-
-#if ENABLE(CSS_FILTERS)
void TextureMapperGL::drawFiltered(const BitmapTexture& sampler, const BitmapTexture* contentTexture, const FilterOperation& filter, int pass)
{
// For standard filters, we always draw the whole texture without transformations.
TextureMapperShaderProgram::Options options = optionsForFilterType(filter.type(), pass);
- RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().getShaderProgram(options);
- ASSERT(program);
+ Ref<TextureMapperShaderProgram> program = data().getShaderProgram(options);
prepareFilterProgram(program.get(), filter, pass, sampler.contentSize(), contentTexture ? static_cast<const BitmapTextureGL*>(contentTexture)->id() : 0);
FloatRect targetRect(IntPoint::zero(), sampler.contentSize());
drawTexturedQuadWithProgram(program.get(), static_cast<const BitmapTextureGL&>(sampler).id(), 0, IntSize(1, 1), targetRect, TransformationMatrix(), 1);
}
-PassRefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper* textureMapper, const FilterOperations& filters)
-{
- if (filters.isEmpty())
- return this;
-
- TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper);
- RefPtr<BitmapTexture> previousSurface = texmapGL->data().currentSurface;
- RefPtr<BitmapTexture> resultSurface = this;
- RefPtr<BitmapTexture> intermediateSurface;
- RefPtr<BitmapTexture> spareSurface;
-
- m_filterInfo = FilterInfo();
-
- for (size_t i = 0; i < filters.size(); ++i) {
- RefPtr<FilterOperation> filter = filters.operations()[i];
- ASSERT(filter);
-
- int numPasses = getPassesRequiredForFilter(filter->type());
- for (int j = 0; j < numPasses; ++j) {
- bool last = (i == filters.size() - 1) && (j == numPasses - 1);
- if (!last) {
- if (!intermediateSurface)
- intermediateSurface = texmapGL->acquireTextureFromPool(contentSize());
- texmapGL->bindSurface(intermediateSurface.get());
- }
-
- if (last) {
- toBitmapTextureGL(resultSurface.get())->m_filterInfo = BitmapTextureGL::FilterInfo(filter, j, spareSurface);
- break;
- }
-
- texmapGL->drawFiltered(*resultSurface.get(), spareSurface.get(), *filter, j);
- if (!j && filter->type() == FilterOperation::DROP_SHADOW) {
- spareSurface = resultSurface;
- resultSurface.clear();
- }
- std::swap(resultSurface, intermediateSurface);
- }
- }
-
- texmapGL->bindSurface(previousSurface.get());
- return resultSurface;
-}
-#endif
-
static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool mirrored)
{
const float nearValue = 9999999;
@@ -926,95 +630,6 @@ static inline TransformationMatrix createProjectionMatrix(const IntSize& size, b
-1, mirrored ? -1 : 1, -(farValue + nearValue) / (farValue - nearValue), 1);
}
-void BitmapTextureGL::initializeStencil()
-{
- if (m_rbo)
- return;
-
- m_rbo = m_context3D->createRenderbuffer();
- m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_rbo);
-#ifdef TEXMAP_OPENGL_ES_2
- m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::STENCIL_INDEX8, m_textureSize.width(), m_textureSize.height());
-#else
- m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_STENCIL, m_textureSize.width(), m_textureSize.height());
-#endif
- m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
- m_context3D->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_rbo);
- m_context3D->clearStencil(0);
- m_context3D->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
-}
-
-void BitmapTextureGL::initializeDepthBuffer()
-{
- if (m_depthBufferObject)
- return;
-
- m_depthBufferObject = m_context3D->createRenderbuffer();
- m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBufferObject);
- m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, m_textureSize.width(), m_textureSize.height());
- m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
- m_context3D->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBufferObject);
-}
-
-void BitmapTextureGL::clearIfNeeded()
-{
- if (!m_shouldClear)
- return;
-
- m_clipStack.reset(IntRect(IntPoint::zero(), m_textureSize), TextureMapperGL::ClipStack::DefaultYAxis);
- m_clipStack.applyIfNeeded(m_context3D.get());
- m_context3D->clearColor(0, 0, 0, 0);
- m_context3D->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
- m_shouldClear = false;
-}
-
-void BitmapTextureGL::createFboIfNeeded()
-{
- if (m_fbo)
- return;
-
- m_fbo = m_context3D->createFramebuffer();
- m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- m_context3D->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, id(), 0);
- m_shouldClear = true;
-}
-
-void BitmapTextureGL::bind(TextureMapperGL* textureMapper)
-{
- m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
- createFboIfNeeded();
- m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- m_context3D->viewport(0, 0, m_textureSize.width(), m_textureSize.height());
- clearIfNeeded();
- textureMapper->data().projectionMatrix = createProjectionMatrix(m_textureSize, true /* mirrored */);
- m_clipStack.apply(m_context3D.get());
-}
-
-BitmapTextureGL::~BitmapTextureGL()
-{
- if (m_id)
- m_context3D->deleteTexture(m_id);
-
- if (m_fbo)
- m_context3D->deleteFramebuffer(m_fbo);
-
- if (m_rbo)
- m_context3D->deleteRenderbuffer(m_rbo);
-
- if (m_depthBufferObject)
- m_context3D->deleteRenderbuffer(m_depthBufferObject);
-}
-
-bool BitmapTextureGL::isValid() const
-{
- return m_id;
-}
-
-IntSize BitmapTextureGL::size() const
-{
- return m_textureSize;
-}
-
TextureMapperGL::~TextureMapperGL()
{
delete m_data;
@@ -1023,11 +638,11 @@ TextureMapperGL::~TextureMapperGL()
void TextureMapperGL::bindDefaultSurface()
{
m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, data().targetFrameBuffer);
- IntSize viewportSize(data().viewport[2], data().viewport[3]);
- data().projectionMatrix = createProjectionMatrix(viewportSize, data().PaintFlags & PaintingMirrored);
- m_context3D->viewport(data().viewport[0], data().viewport[1], viewportSize.width(), viewportSize.height());
- m_clipStack.apply(m_context3D.get());
- data().currentSurface.clear();
+ auto& viewport = data().viewport;
+ data().projectionMatrix = createProjectionMatrix(IntSize(viewport[2], viewport[3]), data().PaintFlags & PaintingMirrored);
+ m_context3D->viewport(viewport[0], viewport[1], viewport[2], viewport[3]);
+ m_clipStack.apply(*m_context3D);
+ data().currentSurface = nullptr;
}
void TextureMapperGL::bindSurface(BitmapTexture *surface)
@@ -1037,10 +652,16 @@ void TextureMapperGL::bindSurface(BitmapTexture *surface)
return;
}
- static_cast<BitmapTextureGL*>(surface)->bind(this);
+ static_cast<BitmapTextureGL*>(surface)->bindAsSurface(m_context3D.get());
+ data().projectionMatrix = createProjectionMatrix(surface->size(), true /* mirrored */);
data().currentSurface = surface;
}
+BitmapTexture* TextureMapperGL::currentSurface()
+{
+ return data().currentSurface.get();
+}
+
bool TextureMapperGL::beginScissorClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect)
{
// 3D transforms are currently not supported in scissor clipping
@@ -1056,7 +677,7 @@ bool TextureMapperGL::beginScissorClip(const TransformationMatrix& modelViewMatr
return false;
clipStack().intersect(rect);
- clipStack().applyIfNeeded(m_context3D.get());
+ clipStack().applyIfNeeded(*m_context3D);
return true;
}
@@ -1068,15 +689,17 @@ void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, con
data().initializeStencil();
- RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().getShaderProgram(TextureMapperShaderProgram::SolidColor);
+ Ref<TextureMapperShaderProgram> program = data().getShaderProgram(TextureMapperShaderProgram::SolidColor);
m_context3D->useProgram(program->programID());
m_context3D->enableVertexAttribArray(program->vertexLocation());
const GC3Dfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
- m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(unitRect));
+ Platform3DObject vbo = data().getStaticVBO(GraphicsContext3D::ARRAY_BUFFER, sizeof(GC3Dfloat) * 8, unitRect);
+ m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vbo);
+ m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, 0);
- TransformationMatrix matrix = TransformationMatrix(modelViewMatrix)
- .multiply(TransformationMatrix::rectToRect(FloatRect(0, 0, 1, 1), targetRect));
+ TransformationMatrix matrix(modelViewMatrix);
+ matrix.multiply(TransformationMatrix::rectToRect(FloatRect(0, 0, 1, 1), targetRect));
static const TransformationMatrix fullProjectionMatrix = TransformationMatrix::rectToRect(FloatRect(0, 0, 1, 1), FloatRect(-1, -1, 2, 2));
@@ -1103,18 +726,19 @@ void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, con
m_context3D->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4);
// Clear the state.
+ m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
m_context3D->disableVertexAttribArray(program->vertexLocation());
m_context3D->stencilMask(0);
// Increase stencilIndex and apply stencil testing.
clipStack().setStencilIndex(stencilIndex * 2);
- clipStack().applyIfNeeded(m_context3D.get());
+ clipStack().applyIfNeeded(*m_context3D);
}
void TextureMapperGL::endClip()
{
clipStack().pop();
- clipStack().applyIfNeeded(m_context3D.get());
+ clipStack().applyIfNeeded(*m_context3D);
}
IntRect TextureMapperGL::clipBounds()
@@ -1124,14 +748,14 @@ IntRect TextureMapperGL::clipBounds()
PassRefPtr<BitmapTexture> TextureMapperGL::createTexture()
{
- BitmapTextureGL* texture = new BitmapTextureGL(this);
- return adoptRef(texture);
+ return BitmapTextureGL::create(*m_context3D);
}
-PassOwnPtr<TextureMapper> TextureMapper::platformCreateAccelerated()
+std::unique_ptr<TextureMapper> TextureMapper::platformCreateAccelerated()
{
- return TextureMapperGL::create();
+ return std::make_unique<TextureMapperGL>();
}
};
-#endif
+
+#endif // USE(TEXTURE_MAPPER_GL)