diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-10 15:31:59 -0800 |
---|---|---|
committer | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-17 13:35:59 -0800 |
commit | 28040489d744e0c5d475a88663056c9040ed5320 (patch) | |
tree | c463676791e4a63e452a95f0a12b2a8519730693 /WebCore/platform/graphics/opengl/TextureMapperGL.cpp | |
parent | eff9be92c41913c92fb1d3b7983c071f3e718678 (diff) | |
download | external_webkit-28040489d744e0c5d475a88663056c9040ed5320.zip external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.gz external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.bz2 |
Merge WebKit at r71558: Initial merge by git.
Change-Id: Ib345578fa29df7e4bc72b4f00e4a6fddcb754c4c
Diffstat (limited to 'WebCore/platform/graphics/opengl/TextureMapperGL.cpp')
-rw-r--r-- | WebCore/platform/graphics/opengl/TextureMapperGL.cpp | 324 |
1 files changed, 198 insertions, 126 deletions
diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp index 6527ce4..03f9b7c 100644 --- a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp +++ b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp @@ -30,8 +30,12 @@ #if defined(TEXMAP_OPENGL_ES_2) #include <GLES2/gl2.h> #elif OS(MAC_OS_X) +#include <AGL/agl.h> #include <gl.h> #else +#if OS(UNIX) +#include <GL/glx.h> +#endif #include <GL/gl.h> #endif @@ -90,6 +94,132 @@ inline static void debugGLCommand(const char* command, int line) #define GL_CMD(x) x #endif +static const GLuint gInVertexAttributeIndex = 0; + +struct TextureMapperGLData { + static struct ShaderInfo { + enum ShaderProgramIndex { + SimpleProgram, + OpacityAndMaskProgram, + TargetProgram, + + ProgramCount + }; + + enum ShaderVariableIndex { + InMatrixVariable, + InSourceMatrixVariable, + InMaskMatrixVariable, + OpacityVariable, + SourceTextureVariable, + MaskTextureVariable, + + VariableCount + }; + + struct ProgramInfo { + GLuint id; + GLint vars[VariableCount]; + }; + + GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name) + { + return programs[prog].vars[var] = glGetUniformLocation(programs[prog].id, name); + } + + void createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource, ShaderProgramIndex index) + { + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + GL_CMD(glShaderSource(vertexShader, 1, &vertexShaderSource, 0)) + GL_CMD(glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0)) + GLuint programID = glCreateProgram(); + GL_CMD(glCompileShader(vertexShader)) + GL_CMD(glCompileShader(fragmentShader)) + GL_CMD(glAttachShader(programID, vertexShader)) + GL_CMD(glAttachShader(programID, fragmentShader)) + GL_CMD(glBindAttribLocation(programID, gInVertexAttributeIndex, "InVertex")) + GL_CMD(glLinkProgram(programID)) + programs[index].id = programID; +#ifdef PRINT_PROGRAM_INFO_LOG + char infoLog[1024]; + int len; + GL_CMD(glGetProgramInfoLog(programID, 1024, &len, infoLog)); + LOG(Graphics, "Compiled program for texture mapper. Log: %s\n", infoLog); +#endif + } + + ProgramInfo programs[ProgramCount]; + + } shaderInfo; + + struct DirectlyCompositedImageRepository { + struct Entry { + GLuint texture; + int refCount; + }; + HashMap<NativeImagePtr, Entry> imageToTexture; + + GLuint findOrCreate(NativeImagePtr image, bool& found) + { + HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); + found = false; + if (it != imageToTexture.end()) { + it->second.refCount++; + found = true; + return it->second.texture; + } + Entry entry; + GL_CMD(glGenTextures(1, &entry.texture)); + entry.refCount = 1; + imageToTexture.add(image, entry); + return entry.texture; + } + + bool deref(NativeImagePtr image) + { + HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); + if (it != imageToTexture.end()) { + if (it->second.refCount < 2) { + imageToTexture.remove(it); + return false; + } + } + return true; + } + + DirectlyCompositedImageRepository() + { + } + + ~DirectlyCompositedImageRepository() + { + for (HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.begin(); it != imageToTexture.end(); ++it) { + GLuint texture = it->second.texture; + if (texture) + GL_CMD(glDeleteTextures(1, &texture)); + } + + } + } directlyCompositedImages; + + TextureMapperGLData() + : currentProgram(TextureMapperGLData::ShaderInfo::TargetProgram) + { } + + TransformationMatrix projectionMatrix; + int currentProgram; + +#if OS(MAC_OS_X) + AGLContext aglContext; +#elif OS(UNIX) + Drawable glxDrawable; + GLXContext glxContext; +#endif +}; + +TextureMapperGLData::ShaderInfo TextureMapperGLData::shaderInfo; + class BitmapTextureGL : public BitmapTexture { public: virtual void destroy(); @@ -99,6 +229,7 @@ public: virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect); virtual void endPaint(); virtual void setContentsToImage(Image*); + ~BitmapTextureGL() { destroy(); } private: GLuint m_id; @@ -111,78 +242,32 @@ private: GLuint m_fbo; IntSize m_actualSize; bool m_surfaceNeedsReset; + TextureMapperGL* m_textureMapper; BitmapTextureGL() : m_id(0) , m_image(0) , m_opaque(false) , m_fbo(0) , m_surfaceNeedsReset(true) + , m_textureMapper(0) { } friend class TextureMapperGL; }; -static struct TexmapShaderInfo { - enum ShaderProgramIndex { - SimpleProgram, - OpacityAndMaskProgram, - TargetProgram, - NumPrograms - }; - - enum ShaderVariableIndex { - InMatrixVariable, - InSourceMatrixVariable, - InMaskMatrixVariable, - InVertexVariable, - - OpacityVariable, - SourceTextureVariable, - MaskTextureVariable, - NumVariables - }; - - struct ProgramInfo { - GLuint id; - GLint vars[NumVariables]; - }; - - GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name) - { - return programs[prog].vars[var] = glGetUniformLocation(programs[prog].id, name); - } - - void createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource, ShaderProgramIndex index) - { - GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - GL_CMD(glShaderSource(vertexShader, 1, &vertexShaderSource, 0)) - GL_CMD(glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0)) - GLuint programID = glCreateProgram(); - GL_CMD(glCompileShader(vertexShader)) - GL_CMD(glCompileShader(fragmentShader)) - GL_CMD(glAttachShader(programID, vertexShader)) - GL_CMD(glAttachShader(programID, fragmentShader)) - GL_CMD(glBindAttribLocation(programID, 0, "InVertex")) - GL_CMD(glLinkProgram(programID)) - programs[index].id = programID; - } - - ProgramInfo programs[NumPrograms]; - -} gShaderInfo; - #define TEXMAP_GET_SHADER_VAR_LOCATION(prog, var) \ - if (gShaderInfo.getUniformLocation(TexmapShaderInfo::prog##Program, TexmapShaderInfo::var##Variable, #var) < 0) \ - LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n"); -#define TEXMAP_BUILD_SHADER(program) gShaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TexmapShaderInfo::program##Program); + if (TextureMapperGLData::shaderInfo.getUniformLocation(TextureMapperGLData::shaderInfo.prog##Program, TextureMapperGLData::shaderInfo.var##Variable, #var) < 0) \ + LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n"); + +#define TEXMAP_BUILD_SHADER(program) \ + TextureMapperGLData::shaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TextureMapperGLData::shaderInfo.program##Program); -TextureMapperGL::TextureMapperGL(GraphicsContext* context) - : TextureMapper(context) - , m_currentProgram(TexmapShaderInfo::TargetProgram) +TextureMapperGL::TextureMapperGL() + : m_data(new TextureMapperGLData) { static bool shadersCompiled = false; + obtainCurrentContext(); if (shadersCompiled) return; shadersCompiled = true; @@ -282,18 +367,18 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture); - TexmapShaderInfo::ShaderProgramIndex program; + TextureMapperGLData::ShaderInfo::ShaderProgramIndex program; if (maskTexture) - program = TexmapShaderInfo::OpacityAndMaskProgram; + program = TextureMapperGLData::ShaderInfo::OpacityAndMaskProgram; else - program = TexmapShaderInfo::SimpleProgram; + program = TextureMapperGLData::ShaderInfo::SimpleProgram; - const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[program]; - if (m_currentProgram != program) { + const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[program]; + if (data().currentProgram != program) { GL_CMD(glUseProgram(programInfo.id)) - GL_CMD(glDisableVertexAttribArray(gShaderInfo.programs[m_currentProgram].vars[TexmapShaderInfo::InVertexVariable])) - m_currentProgram = program; - GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) + GL_CMD(glDisableVertexAttribArray(gInVertexAttributeIndex)) + data().currentProgram = program; + GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex)) } GL_CMD(glDisable(GL_DEPTH_TEST)) @@ -305,7 +390,7 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1}; GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect)) - TransformationMatrix matrix = TransformationMatrix(m_projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix( + TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix( targetRect.width(), 0, 0, 0, 0, targetRect.height(), 0, 0, 0, 0, 1, 0, @@ -321,10 +406,10 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t 0, textureGL.m_relativeSize.height(), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) - GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0)) - GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0)) + GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity)) if (maskTexture && maskTexture->isValid()) { const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture); @@ -334,12 +419,11 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t 0, maskTextureGL->m_relativeSize.height(), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask); - GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::MaskTextureVariable], 1)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask)); + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::MaskTextureVariable], 1)) GL_CMD(glActiveTexture(GL_TEXTURE0)) } - if (textureGL.m_opaque && opacity > 0.99 && !maskTexture) GL_CMD(glDisable(GL_BLEND)) else { @@ -350,7 +434,6 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)) } - const char* TextureMapperGL::type() const { return "OpenGL"; @@ -399,43 +482,6 @@ void BitmapTextureGL::endPaint() m_buffer.clear(); } -struct TexmapGLShaderTextures { - struct Entry { - GLuint texture; - int refCount; - }; - HashMap<NativeImagePtr, Entry> imageToTexture; - GLuint findOrCreate(NativeImagePtr image, bool& found) - { - HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); - found = false; - if (it != imageToTexture.end()) { - it->second.refCount++; - found = true; - return it->second.texture; - } - Entry entry; - GL_CMD(glGenTextures(1, &entry.texture)); - entry.refCount = 1; - imageToTexture.add(image, entry); - return entry.texture; - } - - bool deref(NativeImagePtr image) - { - HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); - if (it != imageToTexture.end()) { - if (it->second.refCount < 2) { - imageToTexture.remove(it); - return false; - } - } - return true; - } -}; - -static TexmapGLShaderTextures gTextureRepository; - void BitmapTextureGL::setContentsToImage(Image* image) { NativeImagePtr nativeImage = image ? image->nativeImageForCurrentFrame() : 0; @@ -448,7 +494,7 @@ void BitmapTextureGL::setContentsToImage(Image* image) if (nativeImage == m_image) return; bool found = false; - GLuint newTextureID = gTextureRepository.findOrCreate(nativeImage, found); + GLuint newTextureID = m_textureMapper->data().directlyCompositedImages.findOrCreate(nativeImage, found); if (newTextureID != m_id) { destroy(); m_id = newTextureID; @@ -464,7 +510,7 @@ void BitmapTextureGL::setContentsToImage(Image* image) void BitmapTextureGL::destroy() { - if (m_id && (!m_image || !gTextureRepository.deref(m_image))) + if (m_id && (!m_image || !m_textureMapper->data().directlyCompositedImages.deref(m_image))) GL_CMD(glDeleteTextures(1, &m_id)) if (m_fbo) GL_CMD(glDeleteFramebuffers(1, &m_fbo)) @@ -493,8 +539,32 @@ static inline TransformationMatrix createProjectionMatrix(const IntSize& size, b -1, flip ? 1 : -1, 0, 1); } -void TextureMapperGL::cleanup() +TextureMapperGL::~TextureMapperGL() { + makeContextCurrent(); + delete m_data; +} + +bool TextureMapperGL::makeContextCurrent() +{ +#if OS(MAC_OS_X) + return aglSetCurrentContext(data().aglContext); +#elif OS(UNIX) + Display* display = XOpenDisplay(0); + if (!display) + return false; + return glXMakeCurrent(display, data().glxDrawable, data().glxContext); +#endif +} + +void TextureMapperGL::obtainCurrentContext() +{ +#if OS(MAC_OS_X) + data().aglContext = aglGetCurrentContext(); +#elif OS(UNIX) + data().glxDrawable = glXGetCurrentDrawable(); + data().glxContext = glXGetCurrentContext(); +#endif } void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) @@ -503,6 +573,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) if (!surface) return; + TransformationMatrix matrix = createProjectionMatrix(surface->size(), false); matrix.translate(-surface->offset().x(), -surface->offset().y()); @@ -520,7 +591,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) } GL_CMD(glViewport(0, 0, surface->size().width(), surface->size().height())) - m_projectionMatrix = matrix; + data().projectionMatrix = matrix; } void TextureMapperGL::setClip(const IntRect& rect) @@ -540,8 +611,7 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize surface.m_actualSize.width(), 0, 0, 0, 0, surface.m_actualSize.height(), 0, 0, 0, 0, 1, 0, - surface.offset().x(), surface.offset().y(), 0, 1 - ) + surface.offset().x(), surface.offset().y(), 0, 1) ); const GLfloat m4[] = { @@ -557,18 +627,18 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize 0, 0, 0, 1}; // We already blended the alpha in; the result is premultiplied. - GL_CMD(glUseProgram(gShaderInfo.programs[TexmapShaderInfo::TargetProgram].id)) + GL_CMD(glUseProgram(data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram].id)) GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0)) GL_CMD(glViewport(0, 0, surfaceSize.width(), surfaceSize.height())) GL_CMD(glDisable(GL_STENCIL_TEST)) - const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[TexmapShaderInfo::TargetProgram]; - GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity)) + const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram]; + GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity)) GL_CMD(glActiveTexture(GL_TEXTURE0)) GL_CMD(glBindTexture(GL_TEXTURE_2D, surface.m_id)) - GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0)) - GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0)) + GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0)) const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1}; GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect)) @@ -577,15 +647,17 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize setClip(visibleRect); GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)) - GL_CMD(glDisableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) + GL_CMD(glDisableVertexAttribArray(0)) GL_CMD(glUseProgram(0)) GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0)) - m_currentProgram = TexmapShaderInfo::TargetProgram; + data().currentProgram = TextureMapperGLData::ShaderInfo::TargetProgram; } PassRefPtr<BitmapTexture> TextureMapperGL::createTexture() { - return adoptRef(new BitmapTextureGL()); + BitmapTextureGL* texture = new BitmapTextureGL(); + texture->m_textureMapper = this; + return adoptRef(texture); } }; |