mirror of https://github.com/stella-emu/stella.git
Move the scaling, streaming and blending options directly into FBSurfaceSDL2,
making this class more robust, and enabling it to be used for either UI surfaces or TIA surfaces. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2884 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
b418d5a4f5
commit
68df6fe891
|
@ -25,7 +25,12 @@ FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 heigh
|
||||||
myFB(buffer),
|
myFB(buffer),
|
||||||
mySurface(NULL),
|
mySurface(NULL),
|
||||||
myTexture(NULL),
|
myTexture(NULL),
|
||||||
mySurfaceIsDirty(true)
|
mySurfaceIsDirty(true),
|
||||||
|
myDataIsStatic(false),
|
||||||
|
myInterpolate(false),
|
||||||
|
myBlendEnabled(false),
|
||||||
|
myBlendAlpha(255),
|
||||||
|
myStaticData(NULL)
|
||||||
{
|
{
|
||||||
// Create a surface in the same format as the parent GL class
|
// Create a surface in the same format as the parent GL class
|
||||||
const SDL_PixelFormat* pf = myFB.myPixelFormat;
|
const SDL_PixelFormat* pf = myFB.myPixelFormat;
|
||||||
|
@ -56,6 +61,12 @@ FBSurfaceSDL2::~FBSurfaceSDL2()
|
||||||
SDL_FreeSurface(mySurface);
|
SDL_FreeSurface(mySurface);
|
||||||
|
|
||||||
free();
|
free();
|
||||||
|
|
||||||
|
if(myStaticData)
|
||||||
|
{
|
||||||
|
delete[] myStaticData;
|
||||||
|
myStaticData = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -92,8 +103,31 @@ void FBSurfaceSDL2::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::basePtr(uInt32*& pixels, uInt32& pitch)
|
void FBSurfaceSDL2::setStaticContents(const uInt32* pixels, uInt32 pitch)
|
||||||
{
|
{
|
||||||
|
myDataIsStatic = true;
|
||||||
|
myStaticPitch = pitch * 4; // we need pitch in 'bytes'
|
||||||
|
|
||||||
|
if(!myStaticData)
|
||||||
|
myStaticData = new uInt32[mySurface->w * mySurface->h];
|
||||||
|
SDL_memcpy(myStaticData, pixels, mySurface->w * mySurface->h);
|
||||||
|
|
||||||
|
// Re-create the texture with the new settings
|
||||||
|
free();
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void FBSurfaceSDL2::setInterpolationAndBlending(
|
||||||
|
bool smoothScale, bool useBlend, uInt32 blendAlpha)
|
||||||
|
{
|
||||||
|
myInterpolate = smoothScale;
|
||||||
|
myBlendEnabled = useBlend;
|
||||||
|
myBlendAlpha = blendAlpha * 2.55;
|
||||||
|
|
||||||
|
// Re-create the texture with the new settings
|
||||||
|
free();
|
||||||
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -147,6 +181,7 @@ void FBSurfaceSDL2::render()
|
||||||
//cerr << "src: x=" << mySrcR.x << ", y=" << mySrcR.y << ", w=" << mySrcR.w << ", h=" << mySrcR.h << endl;
|
//cerr << "src: x=" << mySrcR.x << ", y=" << mySrcR.y << ", w=" << mySrcR.w << ", h=" << mySrcR.h << endl;
|
||||||
//cerr << "dst: x=" << myDstR.x << ", y=" << myDstR.y << ", w=" << myDstR.w << ", h=" << myDstR.h << endl;
|
//cerr << "dst: x=" << myDstR.x << ", y=" << myDstR.y << ", w=" << myDstR.w << ", h=" << myDstR.h << endl;
|
||||||
|
|
||||||
|
if(!myDataIsStatic)
|
||||||
SDL_UpdateTexture(myTexture, &mySrcR, mySurface->pixels, mySurface->pitch);
|
SDL_UpdateTexture(myTexture, &mySrcR, mySurface->pixels, mySurface->pitch);
|
||||||
SDL_RenderCopy(myFB.myRenderer, myTexture, &mySrcR, &myDstR);
|
SDL_RenderCopy(myFB.myRenderer, myTexture, &mySrcR, &myDstR);
|
||||||
|
|
||||||
|
@ -177,7 +212,19 @@ void FBSurfaceSDL2::free()
|
||||||
void FBSurfaceSDL2::reload()
|
void FBSurfaceSDL2::reload()
|
||||||
{
|
{
|
||||||
// Re-create texture; the underlying SDL_Surface is fine as-is
|
// Re-create texture; the underlying SDL_Surface is fine as-is
|
||||||
myTexture = SDL_CreateTexture(myFB.myRenderer,
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, myInterpolate ? "1" : "0");
|
||||||
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
|
myTexture = SDL_CreateTexture(myFB.myRenderer, myFB.myPixelFormat->format,
|
||||||
|
myDataIsStatic ? SDL_TEXTUREACCESS_STATIC : SDL_TEXTUREACCESS_STREAMING,
|
||||||
mySurface->w, mySurface->h);
|
mySurface->w, mySurface->h);
|
||||||
|
|
||||||
|
// If the data is static, we only upload it once
|
||||||
|
if(myDataIsStatic)
|
||||||
|
SDL_UpdateTexture(myTexture, NULL, myStaticData, myStaticPitch);
|
||||||
|
|
||||||
|
// Blending enabled?
|
||||||
|
if(myBlendEnabled)
|
||||||
|
{
|
||||||
|
SDL_SetTextureBlendMode(myTexture, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_SetTextureAlphaMod(myTexture, myBlendAlpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height);
|
FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height);
|
||||||
|
|
||||||
virtual ~FBSurfaceSDL2();
|
virtual ~FBSurfaceSDL2();
|
||||||
|
|
||||||
// Most of the surface drawing primitives are implemented in FBSurface;
|
// Most of the surface drawing primitives are implemented in FBSurface;
|
||||||
|
@ -42,7 +43,9 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
void drawSurface(const FBSurface* surface, uInt32 x, uInt32 y);
|
void drawSurface(const FBSurface* surface, uInt32 x, uInt32 y);
|
||||||
void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
||||||
|
|
||||||
void basePtr(uInt32*& pixels, uInt32& pitch);
|
void setStaticContents(const uInt32* pixels, uInt32 pitch);
|
||||||
|
void setInterpolationAndBlending(bool smoothScale, bool useBlend,
|
||||||
|
uInt32 blendAlpha);
|
||||||
|
|
||||||
GUI::Rect srcRect();
|
GUI::Rect srcRect();
|
||||||
GUI::Rect dstRect();
|
GUI::Rect dstRect();
|
||||||
|
@ -65,6 +68,14 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
SDL_Rect mySrcR, myDstR;
|
SDL_Rect mySrcR, myDstR;
|
||||||
|
|
||||||
bool mySurfaceIsDirty;
|
bool mySurfaceIsDirty;
|
||||||
|
|
||||||
|
bool myDataIsStatic; // Is pixel data constant or can it change?
|
||||||
|
bool myInterpolate; // Scaling is smoothed or blocky
|
||||||
|
bool myBlendEnabled; // Blending is enabled
|
||||||
|
uInt8 myBlendAlpha; // Alpha to use in blending mode
|
||||||
|
|
||||||
|
uInt32* myStaticData; // The data to use when the buffer contents are static
|
||||||
|
uInt32 myStaticPitch; // The number of bytes in a row of static data
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,7 +48,9 @@ class FBSurfaceTIA : public FBSurface
|
||||||
void free();
|
void free();
|
||||||
void reload();
|
void reload();
|
||||||
|
|
||||||
void basePtr(uInt32*& pixels, uInt32& pitch) { }
|
void setStaticContents(const uInt32* pixels, uInt32 pitch) { }
|
||||||
|
void setInterpolationAndBlending(bool smoothScale, bool useBlend,
|
||||||
|
uInt32 blendAlpha) { }
|
||||||
|
|
||||||
GUI::Rect srcRect() { return GUI::Rect(); }
|
GUI::Rect srcRect() { return GUI::Rect(); }
|
||||||
GUI::Rect dstRect() { return GUI::Rect(); }
|
GUI::Rect dstRect() { return GUI::Rect(); }
|
||||||
|
|
|
@ -336,7 +336,7 @@ void FrameBufferSDL2::setTIAPalette(const uInt32* palette)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FBSurface* FrameBufferSDL2::createSurface(int w, int h) const
|
FBSurface* FrameBufferSDL2::createSurface(uInt32 w, uInt32 h) const
|
||||||
{
|
{
|
||||||
return new FBSurfaceSDL2((FrameBufferSDL2&)*this, w, h);
|
return new FBSurfaceSDL2((FrameBufferSDL2&)*this, w, h);
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,13 +165,12 @@ class FrameBufferSDL2 : public FrameBuffer
|
||||||
void invalidate();
|
void invalidate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to create a surface compatible with the one
|
This method is called to create a surface with the given attributes.
|
||||||
currently in use, but having the given dimensions.
|
|
||||||
|
|
||||||
@param w The requested width of the new surface.
|
@param w The requested width of the new surface.
|
||||||
@param h The requested height of the new surface.
|
@param h The requested height of the new surface.
|
||||||
*/
|
*/
|
||||||
FBSurface* createSurface(int w, int h) const;
|
FBSurface* createSurface(uInt32 w, uInt32 h) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Grabs or ungrabs the mouse based on the given boolean value.
|
Grabs or ungrabs the mouse based on the given boolean value.
|
||||||
|
|
|
@ -238,6 +238,30 @@ class FBSurface
|
||||||
virtual void setDstPos(uInt32 x, uInt32 y) = 0;
|
virtual void setDstPos(uInt32 x, uInt32 y) = 0;
|
||||||
virtual void setDstSize(uInt32 w, uInt32 h) = 0;
|
virtual void setDstSize(uInt32 w, uInt32 h) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method should be called to indicate that the surface contains
|
||||||
|
static data that will never change. Some rendering toolkits can
|
||||||
|
use this information to optimize how the data is rendered.
|
||||||
|
|
||||||
|
Note that once this method is called, all other drawing primitives
|
||||||
|
will not work.
|
||||||
|
|
||||||
|
@param pixels The static data to use
|
||||||
|
@param pitch The number of pixels in a row
|
||||||
|
*/
|
||||||
|
virtual void setStaticContents(const uInt32* pixels, uInt32 pitch) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method should be called to modify the interpolation and
|
||||||
|
blending effects to be applied to this surface.
|
||||||
|
|
||||||
|
@param smoothScale Whether to use interpolation during scaling
|
||||||
|
@param useBlend Whether the surface should use alpha blending
|
||||||
|
@param blendAlpha The alpha to use during blending (if used)
|
||||||
|
*/
|
||||||
|
virtual void setInterpolationAndBlending(bool smoothScale,
|
||||||
|
bool useBlend, uInt32 blendAlpha) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method should be called to translate the given coordinates
|
This method should be called to translate the given coordinates
|
||||||
to the (destination) surface coordinates.
|
to the (destination) surface coordinates.
|
||||||
|
|
|
@ -437,13 +437,12 @@ class FrameBuffer
|
||||||
virtual void invalidate() = 0;
|
virtual void invalidate() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to create a surface compatible with the one
|
This method is called to create a surface with the given attributes.
|
||||||
currently in use, but having the given dimensions.
|
|
||||||
|
|
||||||
@param w The requested width of the new surface.
|
@param w The requested width of the new surface.
|
||||||
@param h The requested height of the new surface.
|
@param h The requested height of the new surface.
|
||||||
*/
|
*/
|
||||||
virtual FBSurface* createSurface(int w, int h) const = 0;
|
virtual FBSurface* createSurface(uInt32 w, uInt32 h) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Change scanline intensity and interpolation.
|
Change scanline intensity and interpolation.
|
||||||
|
|
Loading…
Reference in New Issue