Fix in HTML context some specific CSS queries.

Fix several indirect leaks.
Added epp CSS Selector Optimization Plan.
This commit is contained in:
Martín Lucas Golini
2026-07-09 19:51:57 -03:00
parent b0685060f3
commit ce2a73dd3e
6 changed files with 1265 additions and 58 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -836,6 +836,7 @@ struct FcLib {
using FcBool = int;
using FcResult = int;
struct FcConfig;
struct FcPattern;
struct FcObjectSet;
struct FcFontSet {
@@ -872,11 +873,13 @@ struct FcLib {
static constexpr int FC_PROPORTIONAL = 0;
static constexpr int FC_MONO = 100;
FcBool ( *Init )( void );
FcConfig* ( *InitLoadConfigAndFonts )( void );
void ( *ConfigDestroy )( FcConfig* );
void ( *Fini )( void );
FcPattern* ( *PatternCreate )( void );
FcObjectSet* ( *ObjectSetCreate )( void );
FcBool ( *ObjectSetAdd )( FcObjectSet*, const char* );
FcFontSet* ( *FontList )( void*, FcPattern*, FcObjectSet* );
FcFontSet* ( *FontList )( FcConfig*, FcPattern*, FcObjectSet* );
void ( *PatternDestroy )( FcPattern* );
void ( *ObjectSetDestroy )( FcObjectSet* );
void ( *FontSetDestroy )( FcFontSet* );
@@ -890,7 +893,10 @@ struct FcLib {
if ( !handle )
return false;
Init = (decltype( Init ))Sys::loadFunction( handle, "FcInit" );
InitLoadConfigAndFonts = (decltype( InitLoadConfigAndFonts ))Sys::loadFunction(
handle, "FcInitLoadConfigAndFonts" );
ConfigDestroy = (decltype( ConfigDestroy ))Sys::loadFunction( handle, "FcConfigDestroy" );
Fini = (decltype( Fini ))Sys::loadFunction( handle, "FcFini" );
PatternCreate = (decltype( PatternCreate ))Sys::loadFunction( handle, "FcPatternCreate" );
ObjectSetCreate =
(decltype( ObjectSetCreate ))Sys::loadFunction( handle, "FcObjectSetCreate" );
@@ -907,9 +913,15 @@ struct FcLib {
PatternGetInteger =
(decltype( PatternGetInteger ))Sys::loadFunction( handle, "FcPatternGetInteger" );
return Init && PatternCreate && ObjectSetCreate && ObjectSetAdd && FontList &&
PatternDestroy && ObjectSetDestroy && FontSetDestroy && PatternGetString &&
PatternGetInteger;
return InitLoadConfigAndFonts && ConfigDestroy && Fini && PatternCreate &&
ObjectSetCreate && ObjectSetAdd && FontList && PatternDestroy && ObjectSetDestroy &&
FontSetDestroy && PatternGetString && PatternGetInteger;
}
void finish( FcConfig* config ) {
if ( config )
ConfigDestroy( config );
Fini();
}
void unload() {
@@ -970,7 +982,9 @@ void SystemFontResolver::populateFontList() const {
populateFontListFallback();
return;
}
if ( !fc.Init() ) {
FcLib::FcConfig* config = fc.InitLoadConfigAndFonts();
if ( !config ) {
fc.finish( nullptr );
fc.unload();
populateFontListFallback();
return;
@@ -978,20 +992,37 @@ void SystemFontResolver::populateFontList() const {
FcLib::FcPattern* pattern = fc.PatternCreate();
FcLib::FcObjectSet* os = fc.ObjectSetCreate();
fc.ObjectSetAdd( os, "family" );
fc.ObjectSetAdd( os, "file" );
fc.ObjectSetAdd( os, "index" );
fc.ObjectSetAdd( os, "weight" );
fc.ObjectSetAdd( os, "width" );
fc.ObjectSetAdd( os, "slant" );
fc.ObjectSetAdd( os, "spacing" );
if ( !pattern || !os ) {
if ( pattern )
fc.PatternDestroy( pattern );
if ( os )
fc.ObjectSetDestroy( os );
fc.finish( config );
fc.unload();
populateFontListFallback();
return;
}
FcLib::FcFontSet* fontSet = fc.FontList( nullptr, pattern, os );
bool objectSetOk = fc.ObjectSetAdd( os, "family" ) && fc.ObjectSetAdd( os, "file" ) &&
fc.ObjectSetAdd( os, "index" ) && fc.ObjectSetAdd( os, "weight" ) &&
fc.ObjectSetAdd( os, "width" ) && fc.ObjectSetAdd( os, "slant" ) &&
fc.ObjectSetAdd( os, "spacing" );
if ( !objectSetOk ) {
fc.PatternDestroy( pattern );
fc.ObjectSetDestroy( os );
fc.finish( config );
fc.unload();
populateFontListFallback();
return;
}
FcLib::FcFontSet* fontSet = fc.FontList( config, pattern, os );
fc.PatternDestroy( pattern );
fc.ObjectSetDestroy( os );
if ( !fontSet ) {
fc.finish( config );
fc.unload();
populateFontListFallback();
return;
@@ -1036,6 +1067,7 @@ void SystemFontResolver::populateFontList() const {
}
fc.FontSetDestroy( fontSet );
fc.finish( config );
fc.unload();
}

View File

@@ -301,53 +301,67 @@ void TextureLoader::loadFromPixels() {
bool threadedLoad = !Engine::instance()->isMainThread();
if ( threadedLoad && Engine::instance()->isSharedGLContextEnabled() ) {
Engine::instance()->getCurrentWindow()->setGLContextThread();
}
EE::Window::Window* threadedWindow =
threadedLoad && Engine::instance()->isSharedGLContextEnabled()
? Engine::instance()->getCurrentWindow()
: nullptr;
{
ScopedTexture scopedTexture;
struct ScopedThreadGLContext {
EE::Window::Window* window{ nullptr };
if ( !Engine::isEngineRunning() )
return;
if ( mDirectUpload ) {
if ( Image::Format::DDS == mImgType ) {
tTexId = SOIL_direct_load_DDS_from_memory( mPixels, mSize,
SOIL_CREATE_NEW_ID, flags, 0 );
} else if ( Image::Format::PVR == mImgType ) {
tTexId = SOIL_direct_load_PVR_from_memory( mPixels, mSize,
SOIL_CREATE_NEW_ID, flags, 0 );
} else if ( Image::Format::PKM == mImgType ) {
tTexId = SOIL_direct_load_PKM_from_memory( mPixels, mSize,
SOIL_CREATE_NEW_ID, flags );
}
} else {
if ( NULL != mColorKey ) {
mChannels = STBI_rgb_alpha;
Image* tImg = Image::New( mPixels, mImgWidth, mImgHeight, mChannels );
tImg->createMaskFromColor(
Color( mColorKey->r, mColorKey->g, mColorKey->b, 255 ), 0 );
tImg->avoidFreeImage( true );
eeSAFE_DELETE( tImg );
explicit ScopedThreadGLContext( EE::Window::Window* window ) :
window( window ) {
if ( window )
window->setGLContextThread();
}
tTexId = SOIL_create_OGL_texture( mPixels, &width, &height, mChannels,
SOIL_CREATE_NEW_ID, flags );
~ScopedThreadGLContext() {
if ( window )
window->unsetGLContextThread();
}
} scopedThreadGLContext( threadedWindow );
{
ScopedTexture scopedTexture;
if ( !Engine::isEngineRunning() )
return;
if ( mDirectUpload ) {
if ( Image::Format::DDS == mImgType ) {
tTexId = SOIL_direct_load_DDS_from_memory(
mPixels, mSize, SOIL_CREATE_NEW_ID, flags, 0 );
} else if ( Image::Format::PVR == mImgType ) {
tTexId = SOIL_direct_load_PVR_from_memory(
mPixels, mSize, SOIL_CREATE_NEW_ID, flags, 0 );
} else if ( Image::Format::PKM == mImgType ) {
tTexId = SOIL_direct_load_PKM_from_memory( mPixels, mSize,
SOIL_CREATE_NEW_ID, flags );
}
} else {
if ( NULL != mColorKey ) {
mChannels = STBI_rgb_alpha;
Image* tImg = Image::New( mPixels, mImgWidth, mImgHeight, mChannels );
tImg->createMaskFromColor(
Color( mColorKey->r, mColorKey->g, mColorKey->b, 255 ), 0 );
tImg->avoidFreeImage( true );
eeSAFE_DELETE( tImg );
}
tTexId = SOIL_create_OGL_texture( mPixels, &width, &height, mChannels,
SOIL_CREATE_NEW_ID, flags );
}
}
}
if ( threadedLoad ) {
GLi->waitForIdle(); // Lock the thread until the texture has been uploaded to the
// GPU VRAM
}
if ( threadedLoad && Engine::instance()->isSharedGLContextEnabled() ) {
Engine::instance()->getCurrentWindow()->unsetGLContextThread();
if ( threadedLoad ) {
GLi->waitForIdle(); // Lock the thread until the texture has been uploaded to
// the GPU VRAM
}
}
if ( tTexId ) {

View File

@@ -1051,15 +1051,29 @@ const std::string& UIWidget::getStyleSheetTag() const {
}
UIWidget* UIWidget::getStyleSheetParentElement() const {
return NULL != mParentNode && mParentNode->isWidget() ? mParentNode->asType<UIWidget>() : NULL;
return NULL != mParentNode && mParentNode->isWidget() && getType() != UI_TYPE_HTML_HTML
? mParentNode->asType<UIWidget>()
: NULL;
}
UIWidget* UIWidget::getStyleSheetPreviousSiblingElement() const {
return NULL != mPrev && mPrev->isWidget() ? mPrev->asType<UIWidget>() : NULL;
Node* node = mPrev;
while ( NULL != node ) {
if ( node->isWidget() && !node->isTextNode() )
return node->asType<UIWidget>();
node = node->getPrevNode();
}
return NULL;
}
UIWidget* UIWidget::getStyleSheetNextSiblingElement() const {
return NULL != mNext && mNext->isWidget() ? mNext->asType<UIWidget>() : NULL;
Node* node = mNext;
while ( NULL != node ) {
if ( node->isWidget() && !node->isTextNode() )
return node->asType<UIWidget>();
node = node->getNextNode();
}
return NULL;
}
std::vector<const char*> UIWidget::getStyleSheetPseudoClassesStrings() const {

View File

@@ -323,6 +323,7 @@ void WindowSDL::setGLContextThread() {
void WindowSDL::unsetGLContextThread() {
SDL_GL_MakeCurrent( mSDLWindow, nullptr );
SDL_TLSCleanup();
mGLContextMutex.unlock();
}

View File

@@ -298,6 +298,7 @@ void WindowSDL::setGLContextThread() {
void WindowSDL::unsetGLContextThread() {
SDL_GL_MakeCurrent( mSDLWindow, nullptr );
SDL_CleanupTLS();
mGLContextMutex.unlock();
}