1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/gl/TextureImageCGL.mm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,162 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "TextureImageCGL.h" 1.10 +#include "GLContext.h" 1.11 +#include "gfx2DGlue.h" 1.12 +#include "gfxQuartzSurface.h" 1.13 +#include "gfxPlatform.h" 1.14 +#include "gfxFailure.h" 1.15 + 1.16 +namespace mozilla { 1.17 + 1.18 +using namespace gfx; 1.19 + 1.20 +namespace gl { 1.21 + 1.22 +TextureImageCGL::TextureImageCGL(GLuint aTexture, 1.23 + const nsIntSize& aSize, 1.24 + GLenum aWrapMode, 1.25 + ContentType aContentType, 1.26 + GLContext* aContext, 1.27 + TextureImage::Flags aFlags, 1.28 + TextureImage::ImageFormat aImageFormat) 1.29 + : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, 1.30 + aContext, aFlags, aImageFormat) 1.31 + , mPixelBuffer(0) 1.32 + , mPixelBufferSize(0) 1.33 + , mBoundPixelBuffer(false) 1.34 +{} 1.35 + 1.36 +TextureImageCGL::~TextureImageCGL() 1.37 +{ 1.38 + if (mPixelBuffer) { 1.39 + mGLContext->MakeCurrent(); 1.40 + mGLContext->fDeleteBuffers(1, &mPixelBuffer); 1.41 + } 1.42 +} 1.43 + 1.44 +already_AddRefed<gfxASurface> 1.45 +TextureImageCGL::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt) 1.46 +{ 1.47 + IntSize size(aSize.width + 1, aSize.height + 1); 1.48 + mGLContext->MakeCurrent(); 1.49 + if (!mGLContext-> 1.50 + IsExtensionSupported(GLContext::ARB_pixel_buffer_object)) 1.51 + { 1.52 + return gfxPlatform::GetPlatform()-> 1.53 + CreateOffscreenSurface(size, 1.54 + gfxASurface::ContentFromFormat(aFmt)); 1.55 + } 1.56 + 1.57 + if (!mPixelBuffer) { 1.58 + mGLContext->fGenBuffers(1, &mPixelBuffer); 1.59 + } 1.60 + mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer); 1.61 + int32_t length = size.width * 4 * size.height; 1.62 + 1.63 + if (length > mPixelBufferSize) { 1.64 + mGLContext->fBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, length, 1.65 + NULL, LOCAL_GL_STREAM_DRAW); 1.66 + mPixelBufferSize = length; 1.67 + } 1.68 + unsigned char* data = 1.69 + (unsigned char*)mGLContext-> 1.70 + fMapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 1.71 + LOCAL_GL_WRITE_ONLY); 1.72 + 1.73 + mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0); 1.74 + 1.75 + if (!data) { 1.76 + nsAutoCString failure; 1.77 + failure += "Pixel buffer binding failed: "; 1.78 + failure.AppendPrintf("%dx%d\n", size.width, size.height); 1.79 + gfx::LogFailure(failure); 1.80 + 1.81 + mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0); 1.82 + return gfxPlatform::GetPlatform()-> 1.83 + CreateOffscreenSurface(size, 1.84 + gfxASurface::ContentFromFormat(aFmt)); 1.85 + } 1.86 + 1.87 + nsRefPtr<gfxQuartzSurface> surf = 1.88 + new gfxQuartzSurface(data, ThebesIntSize(size), size.width * 4, aFmt); 1.89 + 1.90 + mBoundPixelBuffer = true; 1.91 + return surf.forget(); 1.92 +} 1.93 + 1.94 +bool 1.95 +TextureImageCGL::FinishedSurfaceUpdate() 1.96 +{ 1.97 + if (mBoundPixelBuffer) { 1.98 + mGLContext->MakeCurrent(); 1.99 + mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer); 1.100 + mGLContext->fUnmapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER); 1.101 + return true; 1.102 + } 1.103 + return false; 1.104 +} 1.105 + 1.106 +void 1.107 +TextureImageCGL::FinishedSurfaceUpload() 1.108 +{ 1.109 + if (mBoundPixelBuffer) { 1.110 + mGLContext->MakeCurrent(); 1.111 + mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0); 1.112 + mBoundPixelBuffer = false; 1.113 + } 1.114 +} 1.115 + 1.116 +already_AddRefed<TextureImage> 1.117 +CreateTextureImageCGL(GLContext* gl, 1.118 + const gfx::IntSize& aSize, 1.119 + TextureImage::ContentType aContentType, 1.120 + GLenum aWrapMode, 1.121 + TextureImage::Flags aFlags, 1.122 + TextureImage::ImageFormat aImageFormat) 1.123 +{ 1.124 + if (!gl->IsOffscreenSizeAllowed(aSize) && 1.125 + gfxPlatform::OffMainThreadCompositingEnabled()) { 1.126 + NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!"); 1.127 + nsRefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType, 1.128 + aFlags, aImageFormat); 1.129 + return t.forget(); 1.130 + } 1.131 + 1.132 + return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, 1.133 + aFlags, aImageFormat); 1.134 +} 1.135 + 1.136 +already_AddRefed<TextureImage> 1.137 +TileGenFuncCGL(GLContext *gl, 1.138 + const nsIntSize& aSize, 1.139 + TextureImage::ContentType aContentType, 1.140 + TextureImage::Flags aFlags, 1.141 + TextureImage::ImageFormat aImageFormat) 1.142 +{ 1.143 + bool useNearestFilter = aFlags & TextureImage::UseNearestFilter; 1.144 + gl->MakeCurrent(); 1.145 + 1.146 + GLuint texture; 1.147 + gl->fGenTextures(1, &texture); 1.148 + 1.149 + gl->fActiveTexture(LOCAL_GL_TEXTURE0); 1.150 + gl->fBindTexture(LOCAL_GL_TEXTURE_2D, texture); 1.151 + 1.152 + GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR; 1.153 + gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter); 1.154 + gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter); 1.155 + gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); 1.156 + gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); 1.157 + 1.158 + nsRefPtr<TextureImageCGL> teximage 1.159 + (new TextureImageCGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, 1.160 + gl, aFlags, aImageFormat)); 1.161 + return teximage.forget(); 1.162 +} 1.163 + 1.164 +} 1.165 +}