Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: sky/engine/core/html/canvas/WebGLTexture.cpp

Issue 1001913003: Remove <canvas> (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "sky/engine/config.h"
27
28 #include "sky/engine/core/html/canvas/WebGLTexture.h"
29
30 #include "sky/engine/core/html/canvas/WebGLRenderingContextBase.h"
31
32 namespace blink {
33
34 PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContextBase* ctx)
35 {
36 return adoptRef(new WebGLTexture(ctx));
37 }
38
39 WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
40 : WebGLSharedObject(ctx)
41 , m_target(0)
42 , m_minFilter(GL_NEAREST_MIPMAP_LINEAR)
43 , m_magFilter(GL_LINEAR)
44 , m_wrapS(GL_REPEAT)
45 , m_wrapT(GL_REPEAT)
46 , m_isNPOT(false)
47 , m_isCubeComplete(false)
48 , m_isComplete(false)
49 , m_needToUseBlackTexture(false)
50 , m_isFloatType(false)
51 , m_isHalfFloatType(false)
52 {
53 setObject(ctx->webContext()->createTexture());
54 }
55
56 WebGLTexture::~WebGLTexture()
57 {
58 // Always perform detach here to ensure that platform object
59 // deletion happens with Oilpan enabled. It keeps the code regular
60 // to do it with or without Oilpan enabled.
61 //
62 // See comment in WebGLBuffer's destructor for additional
63 // information on why this is done for WebGLSharedObject-derived
64 // objects.
65 detachAndDeleteObject();
66 }
67
68 void WebGLTexture::setTarget(GLenum target, GLint maxLevel)
69 {
70 if (!object())
71 return;
72 // Target is finalized the first time bindTexture() is called.
73 if (m_target)
74 return;
75 switch (target) {
76 case GL_TEXTURE_2D:
77 m_target = target;
78 m_info.resize(1);
79 m_info[0].resize(maxLevel);
80 break;
81 case GL_TEXTURE_CUBE_MAP:
82 m_target = target;
83 m_info.resize(6);
84 for (int ii = 0; ii < 6; ++ii)
85 m_info[ii].resize(maxLevel);
86 break;
87 }
88 }
89
90 void WebGLTexture::setParameteri(GLenum pname, GLint param)
91 {
92 if (!object() || !m_target)
93 return;
94 switch (pname) {
95 case GL_TEXTURE_MIN_FILTER:
96 switch (param) {
97 case GL_NEAREST:
98 case GL_LINEAR:
99 case GL_NEAREST_MIPMAP_NEAREST:
100 case GL_LINEAR_MIPMAP_NEAREST:
101 case GL_NEAREST_MIPMAP_LINEAR:
102 case GL_LINEAR_MIPMAP_LINEAR:
103 m_minFilter = param;
104 break;
105 }
106 break;
107 case GL_TEXTURE_MAG_FILTER:
108 switch (param) {
109 case GL_NEAREST:
110 case GL_LINEAR:
111 m_magFilter = param;
112 break;
113 }
114 break;
115 case GL_TEXTURE_WRAP_S:
116 switch (param) {
117 case GL_CLAMP_TO_EDGE:
118 case GL_MIRRORED_REPEAT:
119 case GL_REPEAT:
120 m_wrapS = param;
121 break;
122 }
123 break;
124 case GL_TEXTURE_WRAP_T:
125 switch (param) {
126 case GL_CLAMP_TO_EDGE:
127 case GL_MIRRORED_REPEAT:
128 case GL_REPEAT:
129 m_wrapT = param;
130 break;
131 }
132 break;
133 default:
134 return;
135 }
136 update();
137 }
138
139 void WebGLTexture::setParameterf(GLenum pname, GLfloat param)
140 {
141 if (!object() || !m_target)
142 return;
143 GLint iparam = static_cast<GLint>(param);
144 setParameteri(pname, iparam);
145 }
146
147 void WebGLTexture::setLevelInfo(GLenum target, GLint level, GLenum internalForma t, GLsizei width, GLsizei height, GLenum type)
148 {
149 if (!object() || !m_target)
150 return;
151 // We assume level, internalFormat, width, height, and type have all been
152 // validated already.
153 int index = mapTargetToIndex(target);
154 if (index < 0)
155 return;
156 m_info[index][level].setInfo(internalFormat, width, height, type);
157 update();
158 }
159
160 void WebGLTexture::generateMipmapLevelInfo()
161 {
162 if (!object() || !m_target)
163 return;
164 if (!canGenerateMipmaps())
165 return;
166 if (!m_isComplete) {
167 for (size_t ii = 0; ii < m_info.size(); ++ii) {
168 const LevelInfo& info0 = m_info[ii][0];
169 GLsizei width = info0.width;
170 GLsizei height = info0.height;
171 GLint levelCount = computeLevelCount(width, height);
172 for (GLint level = 1; level < levelCount; ++level) {
173 width = std::max(1, width >> 1);
174 height = std::max(1, height >> 1);
175 LevelInfo& info = m_info[ii][level];
176 info.setInfo(info0.internalFormat, width, height, info0.type);
177 }
178 }
179 m_isComplete = true;
180 }
181 m_needToUseBlackTexture = false;
182 }
183
184 GLenum WebGLTexture::getInternalFormat(GLenum target, GLint level) const
185 {
186 const LevelInfo* info = getLevelInfo(target, level);
187 if (!info)
188 return 0;
189 return info->internalFormat;
190 }
191
192 GLenum WebGLTexture::getType(GLenum target, GLint level) const
193 {
194 const LevelInfo* info = getLevelInfo(target, level);
195 if (!info)
196 return 0;
197 return info->type;
198 }
199
200 GLsizei WebGLTexture::getWidth(GLenum target, GLint level) const
201 {
202 const LevelInfo* info = getLevelInfo(target, level);
203 if (!info)
204 return 0;
205 return info->width;
206 }
207
208 GLsizei WebGLTexture::getHeight(GLenum target, GLint level) const
209 {
210 const LevelInfo* info = getLevelInfo(target, level);
211 if (!info)
212 return 0;
213 return info->height;
214 }
215
216 bool WebGLTexture::isValid(GLenum target, GLint level) const
217 {
218 const LevelInfo* info = getLevelInfo(target, level);
219 if (!info)
220 return 0;
221 return info->valid;
222 }
223
224 bool WebGLTexture::isNPOT(GLsizei width, GLsizei height)
225 {
226 ASSERT(width >= 0 && height >= 0);
227 if (!width || !height)
228 return false;
229 if ((width & (width - 1)) || (height & (height - 1)))
230 return true;
231 return false;
232 }
233
234 bool WebGLTexture::isNPOT() const
235 {
236 if (!object())
237 return false;
238 return m_isNPOT;
239 }
240
241 bool WebGLTexture::needToUseBlackTexture(TextureExtensionFlag flag) const
242 {
243 if (!object())
244 return false;
245 if (m_needToUseBlackTexture)
246 return true;
247 if ((m_isFloatType && !(flag & TextureFloatLinearExtensionEnabled)) || (m_is HalfFloatType && !(flag && TextureHalfFloatLinearExtensionEnabled))) {
248 if (m_magFilter != GL_NEAREST || (m_minFilter != GL_NEAREST && m_minFilt er != GL_NEAREST_MIPMAP_NEAREST))
249 return true;
250 }
251 return false;
252 }
253
254 void WebGLTexture::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Plat form3DObject object)
255 {
256 context3d->deleteTexture(object);
257 }
258
259 int WebGLTexture::mapTargetToIndex(GLenum target) const
260 {
261 if (m_target == GL_TEXTURE_2D) {
262 if (target == GL_TEXTURE_2D)
263 return 0;
264 } else if (m_target == GL_TEXTURE_CUBE_MAP) {
265 switch (target) {
266 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
267 return 0;
268 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
269 return 1;
270 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
271 return 2;
272 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
273 return 3;
274 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
275 return 4;
276 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
277 return 5;
278 }
279 }
280 return -1;
281 }
282
283 bool WebGLTexture::canGenerateMipmaps()
284 {
285 if (isNPOT())
286 return false;
287 const LevelInfo& first = m_info[0][0];
288 for (size_t ii = 0; ii < m_info.size(); ++ii) {
289 const LevelInfo& info = m_info[ii][0];
290 if (!info.valid
291 || info.width != first.width || info.height != first.height
292 || info.internalFormat != first.internalFormat || info.type != first .type
293 || (m_info.size() > 1 && !m_isCubeComplete))
294 return false;
295 }
296 return true;
297 }
298
299 GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height)
300 {
301 // return 1 + log2Floor(std::max(width, height));
302 GLsizei n = std::max(width, height);
303 if (n <= 0)
304 return 0;
305 GLint log = 0;
306 GLsizei value = n;
307 for (int ii = 4; ii >= 0; --ii) {
308 int shift = (1 << ii);
309 GLsizei x = (value >> shift);
310 if (x) {
311 value = x;
312 log += shift;
313 }
314 }
315 ASSERT(value == 1);
316 return log + 1;
317 }
318
319 void WebGLTexture::update()
320 {
321 m_isNPOT = false;
322 for (size_t ii = 0; ii < m_info.size(); ++ii) {
323 if (isNPOT(m_info[ii][0].width, m_info[ii][0].height)) {
324 m_isNPOT = true;
325 break;
326 }
327 }
328 m_isComplete = true;
329 m_isCubeComplete = true;
330 const LevelInfo& first = m_info[0][0];
331 GLint levelCount = computeLevelCount(first.width, first.height);
332 if (levelCount < 1)
333 m_isComplete = false;
334 else {
335 for (size_t ii = 0; ii < m_info.size() && m_isComplete; ++ii) {
336 const LevelInfo& info0 = m_info[ii][0];
337 if (!info0.valid
338 || info0.width != first.width || info0.height != first.height
339 || info0.internalFormat != first.internalFormat || info0.type != first.type
340 || (m_info.size() > 1 && info0.width != info0.height)) {
341 if (m_info.size() > 1)
342 m_isCubeComplete = false;
343 m_isComplete = false;
344 break;
345 }
346 GLsizei width = info0.width;
347 GLsizei height = info0.height;
348 for (GLint level = 1; level < levelCount; ++level) {
349 width = std::max(1, width >> 1);
350 height = std::max(1, height >> 1);
351 const LevelInfo& info = m_info[ii][level];
352 if (!info.valid
353 || info.width != width || info.height != height
354 || info.internalFormat != info0.internalFormat || info.type != info0.type) {
355 m_isComplete = false;
356 break;
357 }
358
359 }
360 }
361 }
362 m_isFloatType = m_info[0][0].type == GL_FLOAT;
363 m_isHalfFloatType = m_info[0][0].type == GL_HALF_FLOAT_OES;
364
365 m_needToUseBlackTexture = false;
366 // NPOT
367 if (m_isNPOT && ((m_minFilter != GL_NEAREST && m_minFilter != GL_LINEAR)
368 || m_wrapS != GL_CLAMP_TO_EDGE || m_wrapT != GL_CLAMP_TO_EDGE))
369 m_needToUseBlackTexture = true;
370 // If it is a Cube texture, check Cube Completeness first
371 if (m_info.size() > 1 && !m_isCubeComplete)
372 m_needToUseBlackTexture = true;
373 // Completeness
374 if (!m_isComplete && m_minFilter != GL_NEAREST && m_minFilter != GL_LINEAR)
375 m_needToUseBlackTexture = true;
376 }
377
378 const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GLenum target, GLint l evel) const
379 {
380 if (!object() || !m_target)
381 return 0;
382 int targetIndex = mapTargetToIndex(target);
383 if (targetIndex < 0 || targetIndex >= static_cast<int>(m_info.size()))
384 return 0;
385 if (level < 0 || level >= static_cast<GLint>(m_info[targetIndex].size()))
386 return 0;
387 return &(m_info[targetIndex][level]);
388 }
389
390 }
OLDNEW
« no previous file with comments | « sky/engine/core/html/canvas/WebGLTexture.h ('k') | sky/engine/core/html/canvas/WebGLTexture.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698