15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/canvas/WebGLTexture.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/html/canvas/WebGLRenderingContextBase.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 34c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)PassRefPtrWillBeRawPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContextBase* ctx) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return adoptRefWillBeNoop(new WebGLTexture(ctx)); 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : WebGLSharedObject(ctx) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_target(0) 4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_minFilter(GL_NEAREST_MIPMAP_LINEAR) 4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_magFilter(GL_LINEAR) 4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_wrapS(GL_REPEAT) 4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_wrapT(GL_REPEAT) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_isNPOT(false) 47521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_isCubeComplete(false) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_isComplete(false) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_needToUseBlackTexture(false) 5093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_isFloatType(false) 5193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_isHalfFloatType(false) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 53a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch setObject(ctx->webContext()->createTexture()); 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebGLTexture::~WebGLTexture() 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // Always perform detach here to ensure that platform object 59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // deletion happens with Oilpan enabled. It keeps the code regular 60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // to do it with or without Oilpan enabled. 61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // 62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // See comment in WebGLBuffer's destructor for additional 63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // information on why this is done for WebGLSharedObject-derived 64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // objects. 65c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) detachAndDeleteObject(); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void WebGLTexture::setTarget(GLenum target, GLint maxLevel) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object()) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Target is finalized the first time bindTexture() is called. 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_target) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (target) { 7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_2D: 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_target = target; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_info.resize(1); 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_info[0].resize(maxLevel); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_CUBE_MAP: 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_target = target; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_info.resize(6); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int ii = 0; ii < 6; ++ii) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_info[ii].resize(maxLevel); 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void WebGLTexture::setParameteri(GLenum pname, GLint param) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object() || !m_target) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (pname) { 9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_MIN_FILTER: 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (param) { 9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_NEAREST: 9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_LINEAR: 9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_NEAREST_MIPMAP_NEAREST: 10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_LINEAR_MIPMAP_NEAREST: 10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_NEAREST_MIPMAP_LINEAR: 10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_LINEAR_MIPMAP_LINEAR: 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_minFilter = param; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_MAG_FILTER: 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (param) { 10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_NEAREST: 11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_LINEAR: 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_magFilter = param; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_WRAP_S: 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (param) { 11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_CLAMP_TO_EDGE: 11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_MIRRORED_REPEAT: 11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_REPEAT: 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_wrapS = param; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_WRAP_T: 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (param) { 12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_CLAMP_TO_EDGE: 12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_MIRRORED_REPEAT: 12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_REPEAT: 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_wrapT = param; 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) update(); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void WebGLTexture::setParameterf(GLenum pname, GLfloat param) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object() || !m_target) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 14309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLint iparam = static_cast<GLint>(param); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setParameteri(pname, iparam); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void WebGLTexture::setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object() || !m_target) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We assume level, internalFormat, width, height, and type have all been 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // validated already. 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int index = mapTargetToIndex(target); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index < 0) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_info[index][level].setInfo(internalFormat, width, height, type); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) update(); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WebGLTexture::generateMipmapLevelInfo() 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object() || !m_target) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!canGenerateMipmaps()) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_isComplete) { 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t ii = 0; ii < m_info.size(); ++ii) { 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo& info0 = m_info[ii][0]; 16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLsizei width = info0.width; 17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLsizei height = info0.height; 17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLint levelCount = computeLevelCount(width, height); 17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) for (GLint level = 1; level < levelCount; ++level) { 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) width = std::max(1, width >> 1); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) height = std::max(1, height >> 1); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LevelInfo& info = m_info[ii][level]; 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) info.setInfo(info0.internalFormat, width, height, info0.type); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isComplete = true; 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needToUseBlackTexture = false; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)GLenum WebGLTexture::getInternalFormat(GLenum target, GLint level) const 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo* info = getLevelInfo(target, level); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!info) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return info->internalFormat; 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)GLenum WebGLTexture::getType(GLenum target, GLint level) const 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo* info = getLevelInfo(target, level); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!info) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return info->type; 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)GLsizei WebGLTexture::getWidth(GLenum target, GLint level) const 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo* info = getLevelInfo(target, level); 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!info) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return info->width; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)GLsizei WebGLTexture::getHeight(GLenum target, GLint level) const 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo* info = getLevelInfo(target, level); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!info) 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return info->height; 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLTexture::isValid(GLenum target, GLint level) const 217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const LevelInfo* info = getLevelInfo(target, level); 219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!info) 220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return info->valid; 222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLTexture::isNPOT(GLsizei width, GLsizei height) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(width >= 0 && height >= 0); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!width || !height) 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((width & (width - 1)) || (height & (height - 1))) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool WebGLTexture::isNPOT() const 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object()) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_isNPOT; 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 24193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool WebGLTexture::needToUseBlackTexture(TextureExtensionFlag flag) const 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object()) 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 24593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (m_needToUseBlackTexture) 24693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return true; 24793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if ((m_isFloatType && !(flag & TextureFloatLinearExtensionEnabled)) || (m_isHalfFloatType && !(flag && TextureHalfFloatLinearExtensionEnabled))) { 24809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_magFilter != GL_NEAREST || (m_minFilter != GL_NEAREST && m_minFilter != GL_NEAREST_MIPMAP_NEAREST)) 24993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return true; 25093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 25193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return false; 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void WebGLTexture::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object) 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context3d->deleteTexture(object); 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)int WebGLTexture::mapTargetToIndex(GLenum target) const 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 26109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_target == GL_TEXTURE_2D) { 26209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (target == GL_TEXTURE_2D) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 26409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else if (m_target == GL_TEXTURE_CUBE_MAP) { 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (target) { 26609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 26809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 1; 27009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 2; 27209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 3; 27409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 4; 27609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 5; 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool WebGLTexture::canGenerateMipmaps() 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isNPOT()) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo& first = m_info[0][0]; 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t ii = 0; ii < m_info.size(); ++ii) { 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo& info = m_info[ii][0]; 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!info.valid 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || info.width != first.width || info.height != first.height 292521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) || info.internalFormat != first.internalFormat || info.type != first.type 293521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) || (m_info.size() > 1 && !m_isCubeComplete)) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height) 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // return 1 + log2Floor(std::max(width, height)); 30209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLsizei n = std::max(width, height); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (n <= 0) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 30509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLint log = 0; 30609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLsizei value = n; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int ii = 4; ii >= 0; --ii) { 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int shift = (1 << ii); 30909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLsizei x = (value >> shift); 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (x) { 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value = x; 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log += shift; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(value == 1); 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return log + 1; 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WebGLTexture::update() 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isNPOT = false; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t ii = 0; ii < m_info.size(); ++ii) { 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isNPOT(m_info[ii][0].width, m_info[ii][0].height)) { 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isNPOT = true; 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isComplete = true; 329521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_isCubeComplete = true; 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo& first = m_info[0][0]; 33109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLint levelCount = computeLevelCount(first.width, first.height); 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (levelCount < 1) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isComplete = false; 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t ii = 0; ii < m_info.size() && m_isComplete; ++ii) { 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo& info0 = m_info[ii][0]; 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!info0.valid 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || info0.width != first.width || info0.height != first.height 339521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) || info0.internalFormat != first.internalFormat || info0.type != first.type 340521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) || (m_info.size() > 1 && info0.width != info0.height)) { 341521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (m_info.size() > 1) 342521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_isCubeComplete = false; 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isComplete = false; 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 34609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLsizei width = info0.width; 34709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GLsizei height = info0.height; 34809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) for (GLint level = 1; level < levelCount; ++level) { 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) width = std::max(1, width >> 1); 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) height = std::max(1, height >> 1); 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LevelInfo& info = m_info[ii][level]; 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!info.valid 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || info.width != width || info.height != height 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || info.internalFormat != info0.internalFormat || info.type != info0.type) { 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_isComplete = false; 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 36209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_isFloatType = m_info[0][0].type == GL_FLOAT; 36309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_isHalfFloatType = m_info[0][0].type == GL_HALF_FLOAT_OES; 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needToUseBlackTexture = false; 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // NPOT 36709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_isNPOT && ((m_minFilter != GL_NEAREST && m_minFilter != GL_LINEAR) 36809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) || m_wrapS != GL_CLAMP_TO_EDGE || m_wrapT != GL_CLAMP_TO_EDGE)) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needToUseBlackTexture = true; 370521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // If it is a Cube texture, check Cube Completeness first 371521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (m_info.size() > 1 && !m_isCubeComplete) 372521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_needToUseBlackTexture = true; 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Completeness 37409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!m_isComplete && m_minFilter != GL_NEAREST && m_minFilter != GL_LINEAR) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needToUseBlackTexture = true; 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 37809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GLenum target, GLint level) const 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object() || !m_target) 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int targetIndex = mapTargetToIndex(target); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (targetIndex < 0 || targetIndex >= static_cast<int>(m_info.size())) 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 38509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (level < 0 || level >= static_cast<GLint>(m_info[targetIndex].size())) 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return &(m_info[targetIndex][level]); 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 391