add cache prescaling images

Signed-off-by: Vincent-FK <vincent.buso@funkey-project.com>
This commit is contained in:
Vincent-FK 2020-02-08 07:51:50 +01:00
parent 870255f628
commit 909b7a4dbd
6 changed files with 86 additions and 61 deletions

View File

@ -24,7 +24,7 @@ Component::Component(Page &p)
: page(p)
{
tweens_ = NULL;
backgroundTexture_ = NULL;
//backgroundTexture_ = NULL;
menuScrollReload_ = false;
freeGraphicsMemory();
id_ = -1;
@ -34,7 +34,7 @@ Component::Component(const Component &copy)
: page(copy.page)
{
tweens_ = NULL;
backgroundTexture_ = NULL;
//backgroundTexture_ = NULL;
freeGraphicsMemory();
if ( copy.tweens_ )
@ -65,7 +65,7 @@ void Component::freeGraphicsMemory()
currentTweenComplete_ = true;
elapsedTweenTime_ = 0;
if ( backgroundTexture_ )
/*if ( backgroundTexture_ )
{
SDL_LockMutex(SDL::getMutex());
//SDL_DestroyTexture(backgroundTexture_);
@ -73,14 +73,16 @@ void Component::freeGraphicsMemory()
SDL_UnlockMutex(SDL::getMutex());
backgroundTexture_ = NULL;
}
}*/
}
void Component::allocateGraphicsMemory()
{
#if 0
if ( !backgroundTexture_ )
{
// make a 4x4 pixel wide surface to be stretched during rendering, make it a white background so we can use
// color later
// make a 4x4 pixel wide surface to be stretched during rendering,
// make it a white background so we can use color later
/*SDL_Surface *surface = SDL_CreateRGBSurface(0, 4, 4, 32, 0, 0, 0, 0);
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255));
@ -96,6 +98,7 @@ void Component::allocateGraphicsMemory()
SDL_FillRect(backgroundTexture_, NULL, SDL_MapRGB(backgroundTexture_->format, 255, 255, 255));
SDL_UnlockMutex(SDL::getMutex());
}
#endif
}
@ -215,6 +218,7 @@ void Component::update(float dt)
void Component::draw()
{
#if 0
if ( backgroundTexture_ )
{
SDL_Rect rect;
@ -230,8 +234,9 @@ void Component::draw()
static_cast<char>(baseViewInfo.BackgroundBlue*255));*/
/* For now, no blit, not sure what this surface is good for */
//SDL::renderCopy(backgroundTexture_, baseViewInfo.BackgroundAlpha, NULL, &rect, baseViewInfo);
SDL::renderCopy(backgroundTexture_, baseViewInfo.BackgroundAlpha, NULL, &rect, baseViewInfo);
}
#endif
}
bool Component::animate()

View File

@ -67,8 +67,7 @@ private:
AnimationEvents *tweens_;
Animation *currentTweens_;
//SDL_Texture *backgroundTexture_;
SDL_Surface *backgroundTexture_;
//SDL_Surface *backgroundTexture_;
ViewInfo storeViewInfo_;
unsigned int currentTweenIndex_;

View File

@ -22,6 +22,7 @@
Image::Image(std::string file, std::string altFile, Page &p, float scaleX, float scaleY)
: Component(p)
, texture_(NULL)
, texture_prescaled_(NULL)
, file_(file)
, altFile_(altFile)
, scaleX_(scaleX)
@ -42,10 +43,14 @@ void Image::freeGraphicsMemory()
SDL_LockMutex(SDL::getMutex());
if (texture_ != NULL)
{
//SDL_DestroyTexture(texture_);
SDL_FreeSurface(texture_);
SDL_FreeSurface(texture_);
texture_ = NULL;
}
if (texture_prescaled_ != NULL)
{
SDL_FreeSurface(texture_prescaled_);
texture_prescaled_ = NULL;
}
SDL_UnlockMutex(SDL::getMutex());
}
@ -59,20 +64,20 @@ void Image::allocateGraphicsMemory()
SDL_LockMutex(SDL::getMutex());
/* Load image */
//texture_ = IMG_LoadTexture(SDL::getRenderer(), file_.c_str());
//texture_ = IMG_Load(file_.c_str());
SDL_Surface *img_tmp = NULL;
//printf("Loading image: %s\n", file_.c_str());
img_tmp = IMG_Load(file_.c_str());
if (!img_tmp && altFile_ != "")
{
//texture_ = IMG_LoadTexture(SDL::getRenderer(), altFile_.c_str());
//printf(" Failed-> Loading backup image: %s\n", altFile_.c_str());
img_tmp = IMG_Load(altFile_.c_str());
}
if (img_tmp != NULL)
{
/* Convert to RGB 32bit if necessary */
/* Convert to RGB 32bit if necessary */
if(img_tmp->format->BitsPerPixel != 32){
texture_ = SDL_CreateRGBSurface(0, img_tmp->w, img_tmp->h, 32, 0, 0, 0, 0);
SDL_BlitSurface(img_tmp, NULL, texture_, NULL);
@ -88,12 +93,8 @@ void Image::allocateGraphicsMemory()
/* Set real dimensions */
if (texture_ != NULL)
{
//SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
/*SDL_QueryTexture(texture_, NULL, NULL, &width, &height);
baseViewInfo.ImageWidth = width * scaleX_;
baseViewInfo.ImageHeight = height * scaleY_;*/
baseViewInfo.ImageWidth = texture_->w * scaleX_;
baseViewInfo.ImageHeight = texture_->h * scaleY_;
baseViewInfo.ImageWidth = texture_->w * scaleX_;
baseViewInfo.ImageHeight = texture_->h * scaleY_;
}
}
SDL_UnlockMutex(SDL::getMutex());
@ -107,17 +108,42 @@ void Image::allocateGraphicsMemory()
void Image::draw()
{
bool scaling_needed = false;
bool cache_scaling_needed = false;
bool use_prescaled = false;
Component::draw();
if(texture_)
{
SDL_Rect rect;
rect.x = static_cast<int>(baseViewInfo.XRelativeToOrigin());
rect.y = static_cast<int>(baseViewInfo.YRelativeToOrigin());
rect.h = static_cast<int>(baseViewInfo.ScaledHeight());
rect.w = static_cast<int>(baseViewInfo.ScaledWidth());
SDL::renderCopy(texture_, baseViewInfo.Alpha, NULL, &rect, baseViewInfo);
/* Cache scaling */
scaling_needed = rect.w!=0 && rect.h!=0 && (texture_->w != rect.w || texture_->h != rect.h);
if(scaling_needed){
cache_scaling_needed = (texture_prescaled_ == NULL)?true:(texture_prescaled_->w != rect.w || texture_prescaled_->h != rect.h);
if(cache_scaling_needed){
texture_prescaled_ = SDL::zoomSurface(texture_, NULL, &rect);
if(texture_prescaled_ == NULL){
printf("ERROR in %s - Could not create texture_prescaled_\n", __func__);
use_prescaled = false;
}
}
if(texture_prescaled_ != NULL){
use_prescaled = true;
}
}
if(use_prescaled && texture_prescaled_ != NULL){
SDL::renderCopy(texture_prescaled_, baseViewInfo.Alpha, NULL, &rect, baseViewInfo);
}
else{
SDL::renderCopy(texture_, baseViewInfo.Alpha, NULL, &rect, baseViewInfo);
}
}
}

View File

@ -29,8 +29,8 @@ public:
void draw();
protected:
//SDL_Texture *texture_;
SDL_Surface *texture_;
SDL_Surface *texture_prescaled_;
std::string file_;
std::string altFile_;
float scaleX_;

View File

@ -502,7 +502,7 @@ void NNOptimized(SDL_Surface *src_surface, SDL_Surface *dst_surface, int new_w,
#if 1
/// Nearest neighboor optimized with possible out of screen coordinates (for cropping)
SDL_Surface * SDL::zoomSurface(SDL_Surface *src_surface, SDL_Rect *src_rect, SDL_Rect *dst_rect){
SDL_Surface * SDL::zoomSurface(SDL_Surface *src_surface, SDL_Rect *src_rect_origin, SDL_Rect *dst_rect){
/* Declare vars */
int x_ratio;
@ -510,34 +510,40 @@ SDL_Surface * SDL::zoomSurface(SDL_Surface *src_surface, SDL_Rect *src_rect, SDL
int x2, y2;
int i, j;
int rat;
SDL_Rect srcRect;
/* Sanity checks */
if( src_surface == NULL || dst_rect == NULL || src_rect == NULL){
if(dst_rect == NULL || src_surface == NULL){
printf("ERROR in %s, sanity check\n", __func__);
return NULL;
}
if( dst_rect->w > windowWidth_){
printf("ERROR dst_rect->w (%d) > windowWidth_(%d) \n", dst_rect->w, windowWidth_);
dst_rect->w = windowWidth_;
/* Sanity checks */
if( src_rect_origin == NULL){
srcRect.x = 0;
srcRect.y = 0;
srcRect.w = src_surface->w;
srcRect.h = src_surface->h;
}
if( dst_rect->h > windowHeight_){
printf("ERROR dst_rect->h (%d) > windowHeight_(%d) \n", dst_rect->h, windowHeight_);
dst_rect->h = windowHeight_;
else{
srcRect.x = src_rect_origin->x;
srcRect.y = src_rect_origin->y;
srcRect.w = src_rect_origin->w;
srcRect.h = src_rect_origin->h;
}
if( src_rect->w > src_surface->w){
printf("ERROR src_rect->w (%d) > src_surface->w(%d) \n", src_rect->w, src_surface->w);
src_rect->w = src_surface->w;
if( srcRect.w > src_surface->w){
printf("ERROR src_rect->w (%d) > src_surface->w(%d) \n", srcRect.w, src_surface->w);
srcRect.w = src_surface->w;
}
if( src_rect->h > src_surface->h){
printf("ERROR src_rect->h (%d) > src_surface->h(%d) \n", src_rect->h, src_surface->h);
src_rect->h = src_surface->h;
if( srcRect.h > src_surface->h){
printf("ERROR src_rect->h (%d) > src_surface->h(%d) \n", srcRect.h, src_surface->h);
srcRect.h = src_surface->h;
}
if( src_rect->x > src_surface->w){
printf("ERROR src_rect->x(%d) > src_rect->w(%d) \n", src_rect->x, src_rect->w);
if( srcRect.x > src_surface->w){
printf("ERROR src_rect->x(%d) > src_rect->w(%d) \n", srcRect.x, srcRect.w);
return NULL;
}
if( src_rect->y > src_surface->h){
printf("ERROR src_rect->y (%d) > src_rect->h(%d) \n", src_rect->y, src_rect->h);
if( srcRect.y > src_surface->h){
printf("ERROR src_rect->y (%d) > src_rect->h(%d) \n", srcRect.y, srcRect.h);
return NULL;
}
@ -545,8 +551,8 @@ SDL_Surface * SDL::zoomSurface(SDL_Surface *src_surface, SDL_Rect *src_rect, SDL
src_surface->w, src_surface->h, src_surface->format->BytesPerPixel, src_rect->x, src_rect->y, src_rect->w, src_rect->h, dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h);*/
/* Compute zoom ratio */
x_ratio = (int)((src_rect->w <<16) / dst_rect->w);
y_ratio = (int)((src_rect->h <<16) / dst_rect->h);
x_ratio = (int)((srcRect.w <<16) / dst_rect->w);
y_ratio = (int)((srcRect.h <<16) / dst_rect->h);
/* Create new output surface */
SDL_Surface *dst_surface = SDL_CreateRGBSurface(src_surface->flags,
@ -565,8 +571,8 @@ SDL_Surface * SDL::zoomSurface(SDL_Surface *src_surface, SDL_Rect *src_rect, SDL
/* Get current lines in src and dst surfaces */
uint8_t* t = ( (uint8_t*) dst_surface->pixels + (i*dst_surface->w)*dst_surface->format->BytesPerPixel );
y2 = ((i*y_ratio)>>16);
uint8_t* p = ( (uint8_t*) src_surface->pixels + ((y2+src_rect->y)*src_surface->w)*src_surface->format->BytesPerPixel );
rat = src_rect->x << 16;
uint8_t* p = ( (uint8_t*) src_surface->pixels + ((y2+srcRect.y)*src_surface->w)*src_surface->format->BytesPerPixel );
rat = srcRect.x << 16;
/* Lines iterations */
for (j = 0; j < dst_surface->w; j++)
@ -634,11 +640,6 @@ bool SDL::renderCopy( SDL_Surface *texture, float alpha, SDL_Rect *src, SDL_Rect
{
srcRect.x = 0;
srcRect.y = 0;
/*int w = 0;
int h = 0;
SDL_QueryTexture(texture, NULL, NULL, &w, &h);
srcRect.w = w;
srcRect.h = h;*/
srcRect.w = texture->w;
srcRect.h = texture->h;
}
@ -701,14 +702,8 @@ bool SDL::renderCopy( SDL_Surface *texture, float alpha, SDL_Rect *src, SDL_Rect
}
/* Scaling */
//printf("scaleX : %d, scale Y:%d\n", scaleX, scaleY);
//SDL_SetTextureAlphaMod( texture, static_cast<char>( alpha * 255 ) );
//SDL_RenderCopyEx( getRenderer( ), texture, &srcRect, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_NONE );
//texture = rotozoomSurfaceXY(texture, viewInfo.Angle, scaleX, scaleY, SMOOTHING_OFF);
/*printf("AFTER viewinfo remaniement -> srcRectCopy->w = %d, srcRectCopy->h = %d, dstRectCopy->w = %d, dstRectCopy->h = %d, viewInfo->ContainerWidth = %f, viewInfo->ContainerHeight = %f\n",
srcRectCopy.w, srcRectCopy.h, dstRectCopy.w, dstRectCopy.h, viewInfo.ContainerWidth, viewInfo.ContainerHeight);
printf("AFTER viewinfo remaniement -> srcRect->w = %d, srcRect->h = %d, dstRect->w = %d, dstRect->h = %d, viewInfo->ContainerWidth = %f, viewInfo->ContainerHeight = %f\n",
srcRect.w, srcRect.h, dstRect.w, dstRect.h, viewInfo.ContainerWidth, viewInfo.ContainerHeight);*/
#define WITH_SCALING
#ifdef WITH_SCALING
scaling_needed = !dstRect.w==0 && !dstRect.h==0 && (srcRect.w != dstRect.w || srcRect.h != dstRect.h);
if(scaling_needed){
texture_zoomed = zoomSurface(texture, &srcRect, &dstRect);
@ -719,8 +714,8 @@ bool SDL::renderCopy( SDL_Surface *texture, float alpha, SDL_Rect *src, SDL_Rect
else{
surface_to_blit = texture_zoomed;
}
/*printf("AFTER zoomSurface, texture->w = %d, texture->h = %d\n", texture_zoomed->w, texture_zoomed->h);*/
}
#endif //WITH_SCALING

View File

@ -39,6 +39,7 @@ public:
static SDL_Surface *getWindow( );
static void renderAndFlipWindow( );
//static bool renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo );
static SDL_Surface * zoomSurface(SDL_Surface *surface_ptr, SDL_Rect *src_rect_origin, SDL_Rect *dst_rect);
static bool renderCopy( SDL_Surface *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo );
static int getWindowWidth( )
{
@ -59,7 +60,6 @@ private:
//static SDL_Renderer *renderer_;
static Uint32 get_pixel32( SDL_Surface *surface, int x, int y );
static void put_pixel32( SDL_Surface *surface, int x, int y, Uint32 pixel );
static SDL_Surface * zoomSurface(SDL_Surface *surface_ptr, SDL_Rect *src_rect, SDL_Rect *dst_rect);
static SDL_Surface * flip_surface( SDL_Surface *surface, int flags );
static SDL_Surface *window_;
static SDL_Surface *window_virtual_;