fix some modules's atexit

This commit is contained in:
侯歌 2024-08-19 16:25:52 +08:00
parent 5800616978
commit 163bebcd4d
8 changed files with 39 additions and 193 deletions

View File

@ -1,12 +1,15 @@
#include "atexit.h"
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <memory>
#include <core/atexit.h>
namespace cdroid {
static std::vector<std::function<void()>> *mCallbacks = nullptr;
std::vector<std::function<void()>>& AtExit::callbacks() {
static std::vector<std::function<void()>> callbacks;
return callbacks;
if(mCallbacks==nullptr)
mCallbacks = new std::vector<std::function<void()>>;
return *mCallbacks;
}
std::mutex& AtExit::callbacksMutex() {
@ -16,15 +19,20 @@ std::mutex& AtExit::callbacksMutex() {
void AtExit::registerCallback(std::function<void()> callback) {
std::lock_guard<std::mutex> lock(callbacksMutex());
callbacks().push_back(std::move(callback));
callbacks().push_back(callback);
LOGD("callbacks.size=%d %p",callbacks().size(),&callback);
}
void AtExit::executeCallbacks() {
std::lock_guard<std::mutex> lock(callbacksMutex());
std::for_each(callbacks().rbegin(), callbacks().rend(), [](const std::function<void()>& callback) {
callback();
});
std::vector<std::function<void()>>&cbks = callbacks();
LOGD("AtExit::executeCallbacks %d",int(cbks.size()));
for(auto& callback:cbks) {
if(callback)callback();
}
delete mCallbacks;
}
class AtExit::AtExitInitializer{
public:
AtExitInitializer();
@ -32,9 +40,8 @@ public:
// Ensure callbacks are executed at exit
AtExit::AtExitInitializer::AtExitInitializer(){
std::atexit([] {
AtExit::executeCallbacks();
});
LOGD("**AtExitInitializer::AtExitInitializer");
atexit(AtExit::executeCallbacks);
}
AtExit::AtExitInitializer atExitInitializer;

View File

@ -369,7 +369,7 @@ int Typeface::loadFromFontConfig() {
mSystemLang = lang;
for (int i=0; fs && i < fs->nfont; i++) {
FcPattern *pat = fs->fonts[i];//FcPatternDuplicate(fs->fonts[i]);
Typeface *tf = new Typeface(*pat);
Typeface* tf = new Typeface(*pat);
const std::string family = tf->getFamily();
const std::string style = tf->getStyleName();
std::string font = tf->mFileName;

View File

@ -1,159 +0,0 @@
#include <core/context.h>
#include <cairomm/surface.h>
#include <image-decoders/imagedecoder.h>
#include <gif_lib.h>
#include <cdlog.h>
namespace cdroid{
struct PRIVATE{
std::vector<int>delays;
GifFileType*gif;
}GIFPrivate;
GIFDecoder::GIFDecoder(std::istream&stm):ImageDecoder(stm){
mPrivate = new PRIVATE;
mPrivate->gif=nullptr;
}
GIFDecoder::~GIFDecoder(){
DGifCloseFile(mPrivate->gif,nullptr);
delete mPrivate;
}
#define ARGB(a, r, g, b) ( ((a) & 0xff) << 24 ) | ( ((r) & 0xff) << 16 ) | ( ((g) & 0xff) << 8 ) | ((b) & 0xff)
#define DISPOSE(ext) (((ext)->Bytes[0] & 0x1c) >> 2)
#define TRANS_INDEX(ext) ((ext)->Bytes[3])
#define TRANSPARENCY(ext) ((ext)->Bytes[0] & 1)
#define DELAY(ext) (10*((ext)->Bytes[2] << 8 | (ext)->Bytes[1]))
static int GIFRead(GifFileType *gifFile, GifByteType *buff, int rdlen){
std::istream*is=(std::istream*)gifFile->UserData;
is->read((char*)buff,rdlen);
return is->gcount();
}
static int gifDrawFrame(GifFileType*gif,int current_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1);
int GIFDecoder::decode(bool sizeOnly){
int err;
GifFileType*gifFileType = DGifOpen(istream,GIFRead,&err);
LOGE_IF(gifFileType==nullptr,"git load failed");
if(gifFileType==nullptr)return 0;
DGifSlurp(gifFileType);
mFrameCount = gifFileType->ImageCount;
mPrivate->gif = gifFileType;
mImageWidth = gifFileType->SWidth;
mImageHeight= gifFileType->SHeight;
LOGD("GIF %d frames loaded size(%dx%d)",mFrameCount,mImageWidth,mImageHeight);
return mFrameCount;
}
int GIFDecoder::readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex){
const int duration = gifDrawFrame(mPrivate->gif,frameIndex,image->get_stride(),image->get_data(),false);
if(frameIndex>=mPrivate->delays.size()){
mPrivate->delays.push_back(duration);
}
return duration;
}
int GIFDecoder::getFrameDuration(int frameIndex)const{
return mPrivate->delays.at(frameIndex);
}
static int gifDrawFrame(GifFileType*gif,int current_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1) {
GifColorType *bg;
GifColorType *color;
SavedImage *frame;
ExtensionBlock *ext = nullptr;
GifImageDesc *frameInfo;
ColorMapObject *colorMap;
uint32_t *line;
int width, height, x, y, j;
uint8_t *px = (uint8_t*)pixels;
width = gif->SWidth;
height = gif->SHeight;
frame = &(gif->SavedImages[current_frame]);
frameInfo = &(frame->ImageDesc);
colorMap = frameInfo->ColorMap?frameInfo->ColorMap:gif->SColorMap;
bg = &colorMap->Colors[gif->SBackGroundColor];
for (j = 0; j < frame->ExtensionBlockCount; j++) {
if (frame->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE) {
ext = &(frame->ExtensionBlocks[j]);
break;
}
}
// For DISPOSE = 1, we assume its been drawn
if (ext && DISPOSE(ext) == 1 && force_DISPOSE_1 && current_frame > 0) {
current_frame = current_frame - 1;
gifDrawFrame(gif,current_frame,pxstride, pixels, true);
} else if (ext && DISPOSE(ext) == 2 && bg) {
for (y = 0; y < height; y++) {
line = (uint32_t *) px;
for (x = 0; x < width; x++) {
line[x] = ARGB(255, bg->Red, bg->Green, bg->Blue);
}
px = (px + pxstride);
}
current_frame=(current_frame+1)%gif->ImageCount;
} else if (ext && DISPOSE(ext) == 3 && current_frame > 1) {
current_frame = current_frame - 2;
gifDrawFrame(gif,current_frame,pxstride, pixels, true);
}else current_frame=(current_frame+1)%gif->ImageCount;
px = (uint8_t*)pixels;
const bool isTransparent = TRANSPARENCY(ext);
const int transparentIndex = TRANS_INDEX(ext);
if (frameInfo->Interlace) {
int n = 0, inc = 8, p = 0,loc=0;
px = (px + pxstride * frameInfo->Top);
for (y = frameInfo->Top; y < frameInfo->Top + frameInfo->Height; y++) {
for (x = frameInfo->Left; x < frameInfo->Left + frameInfo->Width; x++) {
loc = (y - frameInfo->Top) * frameInfo->Width + (x - frameInfo->Left);
if (ext && isTransparent && (frame->RasterBits[loc]==transparentIndex)) {
continue;
}
color = (ext && frame->RasterBits[loc] == transparentIndex) ? bg
: &colorMap->Colors[frame->RasterBits[loc]];
if (color)
line[x] = ARGB(255U, color->Red, color->Green, color->Blue);
}
px = (px + pxstride * inc);
n += inc;
if (n >= frameInfo->Height) {
n = 0;
switch (p) {
case 0:
px = (pixels + pxstride * (4 + frameInfo->Top));
inc = 8; p++; break;
case 1:
px = (pixels + pxstride * (2 + frameInfo->Top));
inc = 4; p++; break;
case 2:
px = (pixels + pxstride * (1 + frameInfo->Top));
inc = 2; p++; break;
}
}
}
} else {
px = ( px + pxstride * frameInfo->Top);
for (y = frameInfo->Top; y < frameInfo->Top + frameInfo->Height; y++) {
line = (uint32_t *) px;
for (x = frameInfo->Left; x < frameInfo->Left + frameInfo->Width; x++) {
int loc = (y - frameInfo->Top) * frameInfo->Width + (x - frameInfo->Left);
if (ext && isTransparent &&(frame->RasterBits[loc] == transparentIndex)) {
continue;
}
color = (ext && frame->RasterBits[loc] == transparentIndex) ? bg
: &colorMap->Colors[frame->RasterBits[loc]];
if (color)
line[x] = ARGB(255U, color->Red, color->Green, color->Blue);
}
px +=pxstride;
}
}
return DELAY(ext);
}
}/*endof namespace*/

View File

@ -5,24 +5,19 @@
#include <framesequence.h>
#include <gui/cdroid.h>
#include <core/app.h>
#include <core/textutils.h>
int main(int argc,const char*argv[]){
cdroid::App app(argc,argv);
#if 0
std::unique_ptr<std::ifstream> fstrm = std::make_unique<std::ifstream>(argv[1]);
std::unique_ptr<std::istream> istm = std::move(fstrm);
cdroid::GIFDecoder*dec = new cdroid::GIFDecoder(std::move(istm));
dec->load();
const int frmCount = dec->getFrameCount();
LOGD("imageinfo:%dx%dx%d",dec->getWidth(),dec->getHeight(),frmCount);
Cairo::RefPtr<Cairo::ImageSurface>image
=Cairo::ImageSurface::create(Cairo::Surface::Format::ARGB32,dec->getWidth(),dec->getHeight());
for(int loop=0;loop<10;loop++){
for(int i=0;i<frmCount;i++)
dec->readImage(image,i);
LOGD("loop %d",loop);
}
cdroid::FrameSequence*seq=cdroid::FrameSequence::create(&fin);
#if 1
const char*fname =(argc>1)?argv[1]:"/home/houzh/pf.jpg";
std::ifstream fstrm (fname);
cdroid::ImageDecoder*dec=nullptr;
if(TextUtils::endWith(fname,"png")) dec=new cdroid::PNGDecoder(fstrm);
else dec=new cdroid::JPEGDecoder(fstrm);
Cairo::RefPtr<Cairo::ImageSurface>image=dec->decode(1.234);
LOGD("imageinfo:%dx%d",dec->getWidth(),dec->getHeight());
image->write_to_png("111.png");
//cdroid::FrameSequence*seq=cdroid::FrameSequence::create(&fin);
#else
Window*w=new Window(0,0,-1,-1);
AnimatedImageDrawable*ad=new AnimatedImageDrawable(&app,app.getParam(0,"./Honeycam1.gif"));

View File

@ -2,6 +2,7 @@
#include <view/keyevent.h>
#include <view/motionevent.h>
#include <core/inputdevice.h>
#include <core/atexit.h>
// --- InputEvent ---
namespace cdroid{
@ -57,8 +58,10 @@ void InputEvent::recycle(){
PooledInputEventFactory*PooledInputEventFactory::mInst=nullptr;
PooledInputEventFactory& PooledInputEventFactory::getInstance(){
if(nullptr==mInst)
if(nullptr==mInst){
mInst = new PooledInputEventFactory(20);
AtExit::registerCallback([](){delete mInst;});
}
return *mInst;
}
@ -67,11 +70,11 @@ PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
}
PooledInputEventFactory::~PooledInputEventFactory() {
for (size_t i = 0; i < mKeyEventPool.size(); i++) {
while(!mKeyEventPool.empty()) {
delete mKeyEventPool.front();
mKeyEventPool.pop();
}
for (size_t i = 0; i < mMotionEventPool.size(); i++) {
while(!mMotionEventPool.empty()) {
delete mMotionEventPool.front();
mMotionEventPool.pop();
}

View File

@ -1,5 +1,6 @@
#include <view/layoutinflater.h>
#include <view/viewgroup.h>
#include <core/atexit.h>
#include <cdroid.h>
#include <expat.h>
#include <cdlog.h>
@ -20,7 +21,7 @@ LayoutInflater*LayoutInflater::from(Context*context) {
LayoutInflater*flater = new LayoutInflater(context);
it = mMaps.insert(std::pair<Context*,LayoutInflater*>(context,flater)).first;
if( mMaps.size() ==1) {
atexit([]() {
AtExit::registerCallback([]() {
INFLATERMAPPER& fmap = LayoutInflater::getInflaterMap();
STYLEMAPPER& smap = getStyleMap();
fmap.clear();
@ -28,7 +29,6 @@ LayoutInflater*LayoutInflater::from(Context*context) {
for(auto m:mMaps)
delete m.second;
mMaps.clear();
std::cout<<"LayoutInflater::Destroied!"<<std::endl;
});
}
}

View File

@ -4,4 +4,4 @@ find_package(GTEST)
if (BUILD_CDROID_TESTS AND GTEST_FOUND)
add_subdirectory(gui)
add_subdirectory(porting)
endif(BUILD_CDROID_TESTS)
endif(BUILD_CDROID_TESTS AND GTEST_FOUND)