From 78ed4e230bedbdc11a47bd12ddeb093cde24c78d Mon Sep 17 00:00:00 2001 From: halx99 Date: Fri, 22 Nov 2019 03:36:01 +0800 Subject: [PATCH] TextureFormatEXT --- cocos/2d/CCLabel.cpp | 4 +- cocos/2d/CCNode.cpp | 4 +- cocos/base/ccTypes.h | 18 ++++++++ cocos/renderer/CCTexture2D.cpp | 44 +++++++++++-------- cocos/renderer/CCTexture2D.h | 17 +++---- cocos/renderer/CCTextureCache.cpp | 4 +- cocos/renderer/backend/ProgramCache.cpp | 4 +- .../renderer/backend/ProgramStateRegistry.cpp | 41 +++++++---------- cocos/renderer/backend/ProgramStateRegistry.h | 18 +++----- 9 files changed, 79 insertions(+), 75 deletions(-) diff --git a/cocos/2d/CCLabel.cpp b/cocos/2d/CCLabel.cpp index b7390f7f23..86d268419e 100644 --- a/cocos/2d/CCLabel.cpp +++ b/cocos/2d/CCLabel.cpp @@ -647,7 +647,7 @@ void Label::updateShaderProgram() auto texture = _getTexture(this); if(texture) { - programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getBackendTexture()); + programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getTextureFormatEXT()); } } else @@ -668,7 +668,7 @@ void Label::updateShaderProgram() auto texture = _getTexture(this); if(texture) { - programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getBackendTexture()); + programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getTextureFormatEXT()); } } break; diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 5c3e68fa12..72d8732c6b 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -2184,8 +2184,8 @@ int Node::getAttachedNodeCount() void Node::setProgramStateWithRegistry(backend::ProgramType programType, Texture2D* texture) { - auto n = texture ? texture->getBackendTexture()->getCount() : 1; - setProgramState(backend::ProgramStateRegistry::getInstance()->getProgramState(programType, n)); + auto formatEXT = texture ? texture->getTextureFormatEXT() : 0; + setProgramState(backend::ProgramStateRegistry::getInstance()->getProgramState(programType, formatEXT)); } void Node::updateProgramStateTexture(Texture2D* texture) diff --git a/cocos/base/ccTypes.h b/cocos/base/ccTypes.h index 52ed47ab5a..7eefee934c 100644 --- a/cocos/base/ccTypes.h +++ b/cocos/base/ccTypes.h @@ -634,6 +634,24 @@ struct CC_DLL ScissorRect float height = 0; }; +struct TextureFormatEXT +{ + enum { + NONE = 0, + ETC1_ALPHA = 1, + }; +}; + +struct TextureFlag +{ + enum { + NONE = 0, + ANTIALIAS_ENABLED = 1 << 16, + PREMULTIPLIEDALPHA = 1 << 17, + RENDERTARGET = 1 << 18, + }; +}; + enum class ClearFlag : uint8_t { NONE = 0, diff --git a/cocos/renderer/CCTexture2D.cpp b/cocos/renderer/CCTexture2D.cpp index 107ed4d1c2..499b2d5f83 100644 --- a/cocos/renderer/CCTexture2D.cpp +++ b/cocos/renderer/CCTexture2D.cpp @@ -132,9 +132,7 @@ Texture2D::Texture2D() , _pixelsHigh(0) , _maxS(0.0) , _maxT(0.0) -, _hasPremultipliedAlpha(false) -, _hasMipmaps(false) -, _antialiasEnabled(true) +, _flagsAndFormatEXT(TextureFlag::ANTIALIAS_ENABLED) , _ninePatchInfo(nullptr) , _valid(true) { @@ -212,7 +210,13 @@ void Texture2D::setMaxT(float maxT) bool Texture2D::hasPremultipliedAlpha() const { - return _hasPremultipliedAlpha; + return _flagsAndFormatEXT & TextureFlag::PREMULTIPLIEDALPHA; +} + +void Texture2D::setPremultipliedAlpha(bool premultipliedAlpha) +{ + if (premultipliedAlpha) _flagsAndFormatEXT |= TextureFlag::PREMULTIPLIEDALPHA; + else _flagsAndFormatEXT &= ~TextureFlag::PREMULTIPLIEDALPHA; } bool Texture2D::initWithData(const void *data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/, bool preMultipliedAlpha) @@ -234,7 +238,7 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi return true; } -bool Texture2D::updateWithImage(Image* image, backend::PixelFormat format, int index, bool preMultipliedAlpha) +bool Texture2D::updateWithImage(Image* image, backend::PixelFormat format, int index, int formatEXT) { if (image == nullptr) { @@ -330,8 +334,9 @@ bool Texture2D::updateWithImage(Image* image, backend::PixelFormat format, int i updateWithData(tempData, tempDataLen, imagePixelFormat, renderFormat, imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha(), index); } - if (index > 0) - this->_hasPremultipliedAlpha = preMultipliedAlpha; + _flagsAndFormatEXT |= formatEXT; + if (formatEXT == TextureFormatEXT::ETC1_ALPHA) + setPremultipliedAlpha(true); return true; } @@ -388,14 +393,15 @@ bool Texture2D::updateWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend:: backend::TextureDescriptor textureDescriptor; textureDescriptor.width = pixelsWide; textureDescriptor.height = pixelsHigh; - textureDescriptor.samplerDescriptor.magFilter = (_antialiasEnabled) ? backend::SamplerFilter::LINEAR : backend::SamplerFilter::NEAREST; + + textureDescriptor.samplerDescriptor.magFilter = (_flagsAndFormatEXT & TextureFlag::ANTIALIAS_ENABLED) ? backend::SamplerFilter::LINEAR : backend::SamplerFilter::NEAREST; if (mipmapsNum == 1) { - textureDescriptor.samplerDescriptor.minFilter = (_antialiasEnabled) ? backend::SamplerFilter::LINEAR : backend::SamplerFilter::NEAREST; + textureDescriptor.samplerDescriptor.minFilter = (_flagsAndFormatEXT & TextureFlag::ANTIALIAS_ENABLED) ? backend::SamplerFilter::LINEAR : backend::SamplerFilter::NEAREST; } else { - textureDescriptor.samplerDescriptor.minFilter = (_antialiasEnabled) ? backend::SamplerFilter::LINEAR_MIPMAP_NEAREST : backend::SamplerFilter::NEAREST_MIPMAP_NEAREST; + textureDescriptor.samplerDescriptor.minFilter = (_flagsAndFormatEXT & TextureFlag::ANTIALIAS_ENABLED) ? backend::SamplerFilter::LINEAR_MIPMAP_NEAREST : backend::SamplerFilter::NEAREST_MIPMAP_NEAREST; } int width = pixelsWide; @@ -456,8 +462,7 @@ bool Texture2D::updateWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend:: _maxS = 1; _maxT = 1; - _hasPremultipliedAlpha = preMultipliedAlpha; - _hasMipmaps = mipmapsNum > 1; + setPremultipliedAlpha(preMultipliedAlpha); } return true; @@ -584,7 +589,7 @@ bool Texture2D::initWithString(const char *text, const FontDefinition& textDefin { free(outTempData); } - _hasPremultipliedAlpha = hasPremultipliedAlpha; + setPremultipliedAlpha(hasPremultipliedAlpha); return ret; } @@ -597,14 +602,15 @@ bool Texture2D::initWithBackendTexture(backend::TextureBackend *texture, bool pr CC_ASSERT(_texture); _pixelsWide = _contentSize.width = _texture->getWidth(); _pixelsHigh = _contentSize.height = _texture->getHeight(); - _hasPremultipliedAlpha = preMultipliedAlpha; + setPremultipliedAlpha(preMultipliedAlpha); return true; } void Texture2D::setRenderTarget(bool renderTarget) { - _isRenderTarget = renderTarget; + if (renderTarget) _flagsAndFormatEXT |= TextureFlag::RENDERTARGET; + else _flagsAndFormatEXT &= TextureFlag::RENDERTARGET; } bool Texture2D::hasMipmaps() const @@ -615,12 +621,12 @@ bool Texture2D::hasMipmaps() const void Texture2D::setAliasTexParameters() { - if (! _antialiasEnabled) + if ((_flagsAndFormatEXT & TextureFlag::ANTIALIAS_ENABLED) == 0) { return; } - _antialiasEnabled = false; + _flagsAndFormatEXT &= ~TextureFlag::ANTIALIAS_ENABLED; backend::SamplerDescriptor descriptor( backend::SamplerFilter::NEAREST, //magFilter @@ -634,11 +640,11 @@ void Texture2D::setAliasTexParameters() void Texture2D::setAntiAliasTexParameters() { - if ( _antialiasEnabled ) + if (_flagsAndFormatEXT & TextureFlag::ANTIALIAS_ENABLED) { return; } - _antialiasEnabled = true; + _flagsAndFormatEXT |= TextureFlag::ANTIALIAS_ENABLED; backend::SamplerDescriptor descriptor( backend::SamplerFilter::LINEAR, //magFilter diff --git a/cocos/renderer/CCTexture2D.h b/cocos/renderer/CCTexture2D.h index eccc7af716..af66119b01 100644 --- a/cocos/renderer/CCTexture2D.h +++ b/cocos/renderer/CCTexture2D.h @@ -178,7 +178,7 @@ public: @param width Specifies the width of the texture subimage. @param height Specifies the height of the texture subimage. */ - bool updateWithImage(Image* image, backend::PixelFormat format, int index = 0, bool preMultipliedAlpha = false); + bool updateWithImage(Image* image, backend::PixelFormat format, int index = 0, int formatEXT = 0); bool updateWithData(const void* data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/, bool preMultipliedAlpha, int index = 0); bool updateWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha = false, int index = 0); @@ -245,7 +245,7 @@ public: //TODO: minggo: is it resaonable? bool initWithBackendTexture(backend::TextureBackend* texture, bool preMultipliedAlpha = false); void setRenderTarget(bool renderTarget); - inline bool isRenderTarget() const { return _isRenderTarget; } + inline bool isRenderTarget() const { return _flagsAndFormatEXT & TextureFlag::RENDERTARGET; } void setTexParameters(const TexParams ¶ms); @@ -296,12 +296,14 @@ public: /** Whether or not the texture has their Alpha premultiplied. */ bool hasPremultipliedAlpha() const; + void setPremultipliedAlpha(bool premultipliedAlpha); /** Whether or not the texture has mip maps.*/ bool hasMipmaps() const; /** Gets the pixel format of the texture. */ backend::PixelFormat getPixelFormat() const; + int getTextureFormatEXT() const { return _flagsAndFormatEXT & 0xff; } /** Gets the width of the texture in pixels. */ int getPixelsWide() const; @@ -375,7 +377,7 @@ private: void addSpriteFrameCapInset(SpriteFrame* spritframe, const Rect& capInsets); void initProgram(); - + protected: /** pixel format of the texture */ backend::PixelFormat _pixelFormat; @@ -399,15 +401,10 @@ protected: /** content size */ Size _contentSize; - /** whether or not the texture has their Alpha premultiplied */ - bool _hasPremultipliedAlpha; - - /** whether or not the texture has mip maps*/ - bool _hasMipmaps; + int _flagsAndFormatEXT; static const PixelFormatInfoMap _pixelFormatInfoTables; - bool _antialiasEnabled; NinePatchInfo* _ninePatchInfo; friend class SpriteFrameCache; friend class TextureCache; @@ -420,8 +417,6 @@ protected: backend::UniformLocation _mvpMatrixLocation; backend::UniformLocation _textureLocation; CustomCommand _customCommand; - - bool _isRenderTarget = false; }; diff --git a/cocos/renderer/CCTextureCache.cpp b/cocos/renderer/CCTextureCache.cpp index 5a7f795784..e7f69da981 100644 --- a/cocos/renderer/CCTextureCache.cpp +++ b/cocos/renderer/CCTextureCache.cpp @@ -348,7 +348,7 @@ void TextureCache::addImageAsyncCallBack(float /*dt*/) texture->autorelease(); // ETC1 ALPHA supports. if (asyncStruct->imageAlpha.getFileType() == Image::Format::ETC) { - texture->updateWithImage(&asyncStruct->imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1, true); + texture->updateWithImage(&asyncStruct->imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1, TextureFormatEXT::ETC1_ALPHA); } } else { @@ -421,7 +421,7 @@ Texture2D * TextureCache::addImage(const std::string &path) if (imageAlpha.initWithImageFile(alphaFullPath)) { // pitfall: because we do merge etc1 alpha at shader, so must mark as _hasPremultipliedAlpha=true to makesure alpha blend works well. // the Premultiply operation can only do at shader. - texture->updateWithImage(&imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1, true); + texture->updateWithImage(&imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1, TextureFormatEXT::ETC1_ALPHA); } } diff --git a/cocos/renderer/backend/ProgramCache.cpp b/cocos/renderer/backend/ProgramCache.cpp index b6e9b7e98e..e95c3e8dd4 100644 --- a/cocos/renderer/backend/ProgramCache.cpp +++ b/cocos/renderer/backend/ProgramCache.cpp @@ -118,9 +118,9 @@ bool ProgramCache::init() ** GRAY_SCALE maybe: POSITION_TEXTURE_COLOR_GRAY ** ETC1_GRAY maybe: POSITION_TEXTURE_COLOR_GRAY_ETC1 */ - ProgramStateRegistry::getInstance()->registerProgram(ProgramType::POSITION_TEXTURE_COLOR, 2, + ProgramStateRegistry::getInstance()->registerProgram(ProgramType::POSITION_TEXTURE_COLOR, TextureFormatEXT::ETC1_ALPHA, getBuiltinProgram(ProgramType::ETC1)); - ProgramStateRegistry::getInstance()->registerProgram(ProgramType::GRAY_SCALE, 2, + ProgramStateRegistry::getInstance()->registerProgram(ProgramType::GRAY_SCALE, TextureFormatEXT::ETC1_ALPHA, getBuiltinProgram(ProgramType::ETC1_GRAY)); return true; } diff --git a/cocos/renderer/backend/ProgramStateRegistry.cpp b/cocos/renderer/backend/ProgramStateRegistry.cpp index 59cb02cb1b..be905f5961 100644 --- a/cocos/renderer/backend/ProgramStateRegistry.cpp +++ b/cocos/renderer/backend/ProgramStateRegistry.cpp @@ -31,28 +31,26 @@ bool ProgramStateRegistry::init() return true; } -void ProgramStateRegistry::registerProgram(ProgramType programType, int maxCount, Program* program) +void ProgramStateRegistry::registerProgram(ProgramType programType, int textureFormatEXT, Program* program) { - auto maxIndex = maxCount - 1; - auto it = this->_registry.find(programType); - if (it == this->_registry.end()) { - it = this->_registry.emplace(programType, std::vector{}).first; - it->second.resize(CC_META_TEXTURES); - } - if (maxIndex < it->second.size()) - it->second[maxIndex] = program; + uint32_t key = (static_cast(programType) << 16) | textureFormatEXT; + auto it = this->_registry.find(key); + if (it == this->_registry.end()) + this->_registry.emplace(key, program).first; + else + it->second = program; } void ProgramStateRegistry::clearPrograms() { this->_registry.clear(); } -ProgramState* ProgramStateRegistry::getProgramState(ProgramType programType, int maxCount) +ProgramState* ProgramStateRegistry::getProgramState(ProgramType programType, int textureFormatEXT) { - auto maxIndex = maxCount - 1; - auto it = this->_registry.find(programType); - if (it != this->_registry.end() && it->second.size() > maxIndex) { - auto fallback = it->second[maxIndex]; + uint32_t key = (static_cast(programType) << 16) | textureFormatEXT; + auto it = this->_registry.find(key); + if (it != this->_registry.end()) { + auto fallback = it->second; if (fallback) return new(std::nothrow) ProgramState(fallback); } @@ -60,17 +58,12 @@ ProgramState* ProgramStateRegistry::getProgramState(ProgramType programType, int return new(std::nothrow) ProgramState(Program::getBuiltinProgram((ProgramType)programType)); } -ProgramType ProgramStateRegistry::getProgramType(ProgramType programType, TextureBackend* texture2d) +ProgramType ProgramStateRegistry::getProgramType(ProgramType programType, int textureFormatEXT) { - return this->getProgramType(programType, texture2d->getCount()); -} - -ProgramType ProgramStateRegistry::getProgramType(ProgramType programType, int maxCount) -{ - auto maxIndex = maxCount - 1; - auto it = this->_registry.find(programType); - if (it != this->_registry.end() && it->second.size() > maxIndex) { - auto fallback = it->second[maxIndex]; + uint32_t key = (static_cast(programType) << 16) | textureFormatEXT; + auto it = this->_registry.find(key); + if (it != this->_registry.end()) { + auto fallback = it->second; if (fallback) return fallback->getProgramType(); } diff --git a/cocos/renderer/backend/ProgramStateRegistry.h b/cocos/renderer/backend/ProgramStateRegistry.h index a04973d76f..8dc5d7ba34 100644 --- a/cocos/renderer/backend/ProgramStateRegistry.h +++ b/cocos/renderer/backend/ProgramStateRegistry.h @@ -28,13 +28,6 @@ CC_BACKEND_BEGIN * @{ * #todo: Rename to ProgramStateRegistry */ -/* - Group by programType and texIndex - default, we register: - programType = positionTextureColor, texIndex = 0 ---> positionTextureColorDefault - programType = positionTextureColor, texIndex = 1 ---> positionTextureColorDualETC1 - -*/ class ProgramStateRegistry : public Ref { public: /** returns the shared instance */ @@ -44,17 +37,16 @@ public: static void destroyInstance(); bool init(); - - void registerProgram(ProgramType programType, int maxCount, Program*); void clearPrograms(); - ProgramState* getProgramState(ProgramType programType, int maxCount); - ProgramType getProgramType(ProgramType programType, TextureBackend* texture2d); - ProgramType getProgramType(ProgramType programType, int maxCount); + void registerProgram(ProgramType programType, int textureFormatEXT, Program*); + + ProgramState* getProgramState(ProgramType programType, int textureFormatEXT); + ProgramType getProgramType(ProgramType programType, int textureFormatEXT); protected: - std::unordered_map> _registry; + std::unordered_map _registry; }; //end of _backend group