TextureFormatEXT

This commit is contained in:
halx99 2019-11-22 03:36:01 +08:00
parent 22d5008d28
commit 78ed4e230b
9 changed files with 79 additions and 75 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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 &params);
@ -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;
};

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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<Program*>{}).first;
it->second.resize(CC_META_TEXTURES);
}
if (maxIndex < it->second.size())
it->second[maxIndex] = program;
uint32_t key = (static_cast<uint32_t>(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<uint32_t>(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<uint32_t>(programType) << 16) | textureFormatEXT;
auto it = this->_registry.find(key);
if (it != this->_registry.end()) {
auto fallback = it->second;
if (fallback)
return fallback->getProgramType();
}

View File

@ -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<ProgramType, std::vector<Program*>> _registry;
std::unordered_map<uint32_t, Program*> _registry;
};
//end of _backend group