gfx/gl/TextureImageCGL.mm

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:867e89290af1
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "TextureImageCGL.h"
7 #include "GLContext.h"
8 #include "gfx2DGlue.h"
9 #include "gfxQuartzSurface.h"
10 #include "gfxPlatform.h"
11 #include "gfxFailure.h"
12
13 namespace mozilla {
14
15 using namespace gfx;
16
17 namespace gl {
18
19 TextureImageCGL::TextureImageCGL(GLuint aTexture,
20 const nsIntSize& aSize,
21 GLenum aWrapMode,
22 ContentType aContentType,
23 GLContext* aContext,
24 TextureImage::Flags aFlags,
25 TextureImage::ImageFormat aImageFormat)
26 : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType,
27 aContext, aFlags, aImageFormat)
28 , mPixelBuffer(0)
29 , mPixelBufferSize(0)
30 , mBoundPixelBuffer(false)
31 {}
32
33 TextureImageCGL::~TextureImageCGL()
34 {
35 if (mPixelBuffer) {
36 mGLContext->MakeCurrent();
37 mGLContext->fDeleteBuffers(1, &mPixelBuffer);
38 }
39 }
40
41 already_AddRefed<gfxASurface>
42 TextureImageCGL::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
43 {
44 IntSize size(aSize.width + 1, aSize.height + 1);
45 mGLContext->MakeCurrent();
46 if (!mGLContext->
47 IsExtensionSupported(GLContext::ARB_pixel_buffer_object))
48 {
49 return gfxPlatform::GetPlatform()->
50 CreateOffscreenSurface(size,
51 gfxASurface::ContentFromFormat(aFmt));
52 }
53
54 if (!mPixelBuffer) {
55 mGLContext->fGenBuffers(1, &mPixelBuffer);
56 }
57 mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
58 int32_t length = size.width * 4 * size.height;
59
60 if (length > mPixelBufferSize) {
61 mGLContext->fBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, length,
62 NULL, LOCAL_GL_STREAM_DRAW);
63 mPixelBufferSize = length;
64 }
65 unsigned char* data =
66 (unsigned char*)mGLContext->
67 fMapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER,
68 LOCAL_GL_WRITE_ONLY);
69
70 mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
71
72 if (!data) {
73 nsAutoCString failure;
74 failure += "Pixel buffer binding failed: ";
75 failure.AppendPrintf("%dx%d\n", size.width, size.height);
76 gfx::LogFailure(failure);
77
78 mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
79 return gfxPlatform::GetPlatform()->
80 CreateOffscreenSurface(size,
81 gfxASurface::ContentFromFormat(aFmt));
82 }
83
84 nsRefPtr<gfxQuartzSurface> surf =
85 new gfxQuartzSurface(data, ThebesIntSize(size), size.width * 4, aFmt);
86
87 mBoundPixelBuffer = true;
88 return surf.forget();
89 }
90
91 bool
92 TextureImageCGL::FinishedSurfaceUpdate()
93 {
94 if (mBoundPixelBuffer) {
95 mGLContext->MakeCurrent();
96 mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
97 mGLContext->fUnmapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER);
98 return true;
99 }
100 return false;
101 }
102
103 void
104 TextureImageCGL::FinishedSurfaceUpload()
105 {
106 if (mBoundPixelBuffer) {
107 mGLContext->MakeCurrent();
108 mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
109 mBoundPixelBuffer = false;
110 }
111 }
112
113 already_AddRefed<TextureImage>
114 CreateTextureImageCGL(GLContext* gl,
115 const gfx::IntSize& aSize,
116 TextureImage::ContentType aContentType,
117 GLenum aWrapMode,
118 TextureImage::Flags aFlags,
119 TextureImage::ImageFormat aImageFormat)
120 {
121 if (!gl->IsOffscreenSizeAllowed(aSize) &&
122 gfxPlatform::OffMainThreadCompositingEnabled()) {
123 NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!");
124 nsRefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType,
125 aFlags, aImageFormat);
126 return t.forget();
127 }
128
129 return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode,
130 aFlags, aImageFormat);
131 }
132
133 already_AddRefed<TextureImage>
134 TileGenFuncCGL(GLContext *gl,
135 const nsIntSize& aSize,
136 TextureImage::ContentType aContentType,
137 TextureImage::Flags aFlags,
138 TextureImage::ImageFormat aImageFormat)
139 {
140 bool useNearestFilter = aFlags & TextureImage::UseNearestFilter;
141 gl->MakeCurrent();
142
143 GLuint texture;
144 gl->fGenTextures(1, &texture);
145
146 gl->fActiveTexture(LOCAL_GL_TEXTURE0);
147 gl->fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
148
149 GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
150 gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
151 gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
152 gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
153 gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
154
155 nsRefPtr<TextureImageCGL> teximage
156 (new TextureImageCGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType,
157 gl, aFlags, aImageFormat));
158 return teximage.forget();
159 }
160
161 }
162 }

mercurial