added in locking/unlocking of surfaces when accessing underlying pixel data
This commit is contained in:
parent
d0b52226a5
commit
c3c0cc50c5
10 changed files with 87 additions and 50 deletions
|
@ -93,7 +93,8 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
|
|||
SDL_Surface* const disp = screen_.getSurface();
|
||||
const int length = disp->w*disp->h;
|
||||
|
||||
short* const pixels = reinterpret_cast<short*>(disp->pixels);
|
||||
surface_lock lock(disp);
|
||||
short* const pixels = lock.pixels();
|
||||
std::fill(pixels,pixels+length,0);
|
||||
}
|
||||
|
||||
|
@ -744,7 +745,9 @@ void display::draw_minimap(int x, int y, int w, int h)
|
|||
|
||||
const Pixel boxcolour = Pixel(SDL_MapRGB(surface->format,0xFF,0xFF,0xFF));
|
||||
SDL_Surface* const screen = screen_.getSurface();
|
||||
short* const data = reinterpret_cast<short*>(screen->pixels);
|
||||
|
||||
surface_lock lock(screen);
|
||||
short* const data = lock.pixels();
|
||||
short* const start_top = data + (y+ybox)*screen->w + (x+xbox);
|
||||
short* const end_top = start_top + wbox;
|
||||
|
||||
|
@ -1048,16 +1051,17 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image,
|
|||
}
|
||||
|
||||
const int srcy = minimum<int>(yloc,surface->h-1);
|
||||
short* startsrc = reinterpret_cast<short*>(surface->pixels) +
|
||||
srcy*(surface->w+xpad) + (xoffset > xsrc ? xoffset:xsrc);
|
||||
|
||||
surface_lock srclock(surface);
|
||||
short* startsrc = srclock.pixels() + srcy*(surface->w+xpad) +
|
||||
(xoffset > xsrc ? xoffset:xsrc);
|
||||
short* endsrc = startsrc + len;
|
||||
|
||||
assert(startsrc >= reinterpret_cast<short*>(surface->pixels) &&
|
||||
endsrc <= reinterpret_cast<short*>(surface->pixels) +
|
||||
(surface->w+xpad)*surface->h);
|
||||
assert(startsrc >= srclock.pixels() &&
|
||||
endsrc <= srclock.pixels() + (surface->w+xpad)*surface->h);
|
||||
|
||||
short* startdst =
|
||||
reinterpret_cast<short*>(dst->pixels) + j*dst->w + xdst;
|
||||
surface_lock dstlock(dst);
|
||||
short* startdst = dstlock.pixels() + j*dst->w + xdst;
|
||||
std::copy(startsrc,endsrc,startdst);
|
||||
|
||||
int extra = 0;
|
||||
|
@ -1074,7 +1078,9 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image,
|
|||
ov != overlaps.end(); ++ov) {
|
||||
const int srcy = minimum<int>(yloc,(*ov)->h-1);
|
||||
const int w = (*ov)->w + is_odd((*ov)->w);
|
||||
short* beg = reinterpret_cast<short*>((*ov)->pixels) +
|
||||
|
||||
surface_lock overlap_lock(*ov);
|
||||
short* beg = overlap_lock.pixels() +
|
||||
srcy*w + (xoffset > xsrc ? xoffset:xsrc);
|
||||
short* end = beg + len;
|
||||
short* dst = startdst;
|
||||
|
@ -1130,6 +1136,9 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image,
|
|||
|
||||
const bool energy_uses_alpha = highlight_ratio < 1.0 && blend_with == 0;
|
||||
|
||||
surface_lock dstlock(dst);
|
||||
surface_lock energy_lock(energy_image);
|
||||
|
||||
for(j = ypos; j != yend; ++j) {
|
||||
const int yloc = ysrc+j-ypos;
|
||||
const int xoffset = abs(yloc - static_cast<int>(zoom_/2.0))/2;
|
||||
|
@ -1144,8 +1153,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image,
|
|||
const int maxlen = static_cast<int>(zoom_) - xoffset*2;
|
||||
int len = ((xend - xdst) > maxlen) ? maxlen : xend - xdst;
|
||||
|
||||
short* startdst =
|
||||
reinterpret_cast<short*>(dst->pixels) + j*dst->w + xdst;
|
||||
short* startdst = dstlock.pixels() + j*dst->w + xdst;
|
||||
|
||||
const Pixel replace_energy =
|
||||
Pixel(SDL_MapRGB(energy_image->format,0xFF,0xFF,0xFF));
|
||||
|
@ -1158,8 +1166,8 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image,
|
|||
|
||||
const int energy_w = energy_image->w + is_odd(energy_image->w);
|
||||
if(yloc + skip < energy_image->h) {
|
||||
startenergy = reinterpret_cast<short*>(energy_image->pixels) +
|
||||
(yloc+skip)*energy_w + (xoffset > xsrc ? xoffset:xsrc);
|
||||
startenergy = energy_lock.pixels() + (yloc+skip)*energy_w +
|
||||
maximum(xoffset,xsrc);
|
||||
|
||||
for(int i = 0; i != len; ++i) {
|
||||
if(startenergy != NULL && *startenergy != 0) {
|
||||
|
@ -1326,9 +1334,6 @@ void display::blit_surface(int x, int y, SDL_Surface* surface)
|
|||
if(srcw <= 0 || srch <= 0 || srcx >= surface->w || srcy >= surface->h)
|
||||
return;
|
||||
|
||||
SDL_LockSurface(surface);
|
||||
SDL_LockSurface(target);
|
||||
|
||||
if(x < 0)
|
||||
x = 0;
|
||||
|
||||
|
@ -1340,9 +1345,11 @@ void display::blit_surface(int x, int y, SDL_Surface* surface)
|
|||
const int padding = is_odd(surface->w);
|
||||
const int surface_width = surface->w + padding;
|
||||
|
||||
const short* src = reinterpret_cast<short*>(surface->pixels) +
|
||||
srcy*surface_width + srcx;
|
||||
short* dst = reinterpret_cast<short*>(target->pixels) + y*target->w + x;
|
||||
surface_lock srclock(surface);
|
||||
surface_lock dstlock(target);
|
||||
|
||||
const short* src = srclock.pixels() + srcy*surface_width + srcx;
|
||||
short* dst = dstlock.pixels() + y*target->w + x;
|
||||
|
||||
static const short transperant = 0;
|
||||
|
||||
|
@ -1359,8 +1366,6 @@ void display::blit_surface(int x, int y, SDL_Surface* surface)
|
|||
++d;
|
||||
}
|
||||
}
|
||||
SDL_UnlockSurface(surface);
|
||||
SDL_UnlockSurface(target);
|
||||
}
|
||||
|
||||
SDL_Surface* display::getImage(const std::string& filename,
|
||||
|
@ -1452,9 +1457,11 @@ SDL_Surface* display::getImageTinted(const std::string& filename, TINT tint)
|
|||
|
||||
image_map.insert(std::pair<std::string,SDL_Surface*>(filename,surface));
|
||||
|
||||
short* begin = reinterpret_cast<short*>(base->pixels);
|
||||
surface_lock srclock(base);
|
||||
surface_lock dstlock(surface);
|
||||
short* begin = srclock.pixels();
|
||||
const short* const end = begin + base->h*(base->w + (base->w%2));
|
||||
short* dest = reinterpret_cast<short*>(surface->pixels);
|
||||
short* dest = dstlock.pixels();
|
||||
|
||||
const int rmax = 0xFF;
|
||||
const int gmax = 0xFF;
|
||||
|
@ -1512,7 +1519,8 @@ SDL_Surface* display::getMinimap(int w, int h)
|
|||
|
||||
const int xpad = is_odd(minimap_->w);
|
||||
|
||||
short* data = reinterpret_cast<short*>(minimap_->pixels);
|
||||
surface_lock lock(minimap_);
|
||||
short* data = lock.pixels();
|
||||
for(int y = 0; y != map_.y(); ++y) {
|
||||
for(int x = 0; x != map_.x(); ++x) {
|
||||
|
||||
|
@ -1915,7 +1923,7 @@ void display::move_unit_between(const gamemap::location& a,
|
|||
|
||||
//checking keys may have invalidated all images (if they have
|
||||
//zoomed in or out), so reget the image here
|
||||
const SDL_Surface* const image = getImage(u.type().image());
|
||||
SDL_Surface* const image = getImage(u.type().image());
|
||||
if(image == NULL) {
|
||||
std::cerr << "failed to get image " << u.type().image() << "\n";
|
||||
return;
|
||||
|
@ -1993,7 +2001,7 @@ void display::move_unit_between(const gamemap::location& a,
|
|||
}
|
||||
}
|
||||
|
||||
void display::draw_unit(int x, int y, const SDL_Surface* image,
|
||||
void display::draw_unit(int x, int y, SDL_Surface* image,
|
||||
bool reverse, bool upside_down,
|
||||
double alpha, Pixel blendto)
|
||||
{
|
||||
|
@ -2010,7 +2018,8 @@ void display::draw_unit(int x, int y, const SDL_Surface* image,
|
|||
|
||||
SDL_Surface* const screen = screen_.getSurface();
|
||||
|
||||
const Pixel* src = reinterpret_cast<const short*>(image->pixels);
|
||||
surface_lock srclock(image);
|
||||
const Pixel* src = srclock.pixels();
|
||||
|
||||
const int endy = (y + image->h) < h ? (y + image->h) : h;
|
||||
const int endx = (x + image->w) < w ? (x + image->w) : w;
|
||||
|
@ -2046,9 +2055,10 @@ void display::draw_unit(int x, int y, const SDL_Surface* image,
|
|||
|
||||
const int src_increment = image_w * (upside_down ? -1 : 1);
|
||||
|
||||
surface_lock screen_lock(screen);
|
||||
|
||||
for(; y != endy; ++y, src += src_increment) {
|
||||
Pixel* dst =
|
||||
reinterpret_cast<Pixel*>(screen->pixels) + y*screen->w + x;
|
||||
Pixel* dst = screen_lock.pixels() + y*screen->w + x;
|
||||
|
||||
if(alpha == 1.0) {
|
||||
if(reverse) {
|
||||
|
@ -2096,8 +2106,10 @@ const std::pair<int,int>& display::calculate_energy_bar()
|
|||
int first_row = -1;
|
||||
int last_row = -1;
|
||||
|
||||
const SDL_Surface* const image = getImage("unmoved-energy.png");
|
||||
const short* const begin = reinterpret_cast<short*>(image->pixels);
|
||||
SDL_Surface* const image = getImage("unmoved-energy.png");
|
||||
|
||||
surface_lock image_lock(image);
|
||||
const short* const begin = image_lock.pixels();
|
||||
|
||||
const Pixel colour = Pixel(SDL_MapRGB(image->format,0xFF,0xFF,0xFF));
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ private:
|
|||
const gamemap::location& b,
|
||||
const unit& u);
|
||||
|
||||
void draw_unit(int x, int y, const SDL_Surface* image,
|
||||
void draw_unit(int x, int y, SDL_Surface* image,
|
||||
bool reverse, bool upside_down=false,
|
||||
double alpha=1.0, short blendto=0);
|
||||
|
||||
|
|
|
@ -51,7 +51,9 @@ void draw_rectangle(int x, int y, int w, int h, short colour,
|
|||
return;
|
||||
}
|
||||
|
||||
short* top_left = reinterpret_cast<short*>(target->pixels) + target->w*y+x;
|
||||
surface_lock dstlock(target);
|
||||
|
||||
short* top_left = dstlock.pixels() + target->w*y+x;
|
||||
short* top_right = top_left + w;
|
||||
short* bot_left = top_left + target->w*h;
|
||||
short* bot_right = bot_left + w;
|
||||
|
@ -76,8 +78,10 @@ void draw_solid_tinted_rectangle(int x, int y, int w, int h,
|
|||
return;
|
||||
}
|
||||
|
||||
surface_lock dstlock(target);
|
||||
|
||||
const SDL_PixelFormat* const fmt = target->format;
|
||||
short* p = reinterpret_cast<short*>(target->pixels) + target->w*y + x;
|
||||
short* p = dstlock.pixels() + target->w*y + x;
|
||||
while(h > 0) {
|
||||
short* beg = p;
|
||||
short* const end = p + w;
|
||||
|
|
|
@ -38,6 +38,9 @@ SDL_Surface* scale_surface(SDL_Surface* surface, int w, int h)
|
|||
const int srcxpad = is_odd(surface->w);
|
||||
const int dstxpad = is_odd(dest->w);
|
||||
|
||||
surface_lock dstlock(dest);
|
||||
surface_lock srclock(surface);
|
||||
|
||||
double ysrc = 0.0;
|
||||
for(int ydst = 0; ydst != h; ++ydst, ysrc += yratio) {
|
||||
double xsrc = 0.0;
|
||||
|
@ -49,9 +52,8 @@ SDL_Surface* scale_surface(SDL_Surface* surface, int w, int h)
|
|||
|
||||
const int dstpad = dstxpad*ydst;
|
||||
|
||||
reinterpret_cast<short*>(dest->pixels)[ydst*w + xdst + dstpad] =
|
||||
reinterpret_cast<short*>(surface->pixels)[
|
||||
ysrcint*surface->w + xsrcint];
|
||||
srclock.pixels()[ydst*w + xdst + dstpad] =
|
||||
dstlock.pixels()[ysrcint*surface->w + xsrcint];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,4 +81,28 @@ struct pixel_data
|
|||
int r, g, b;
|
||||
};
|
||||
|
||||
struct surface_lock
|
||||
{
|
||||
surface_lock(SDL_Surface* surface) : surface_(surface), locked_(false)
|
||||
{
|
||||
if(SDL_MUSTLOCK(surface_)) {
|
||||
const int res = SDL_LockSurface(surface_);
|
||||
if(res == 0) {
|
||||
locked_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~surface_lock()
|
||||
{
|
||||
if(locked_)
|
||||
SDL_UnlockSurface(surface_);
|
||||
}
|
||||
|
||||
short* pixels() { return reinterpret_cast<short*>(surface_->pixels); }
|
||||
private:
|
||||
SDL_Surface* const surface_;
|
||||
bool locked_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -163,11 +163,6 @@ int CVideo::getBlueMask()
|
|||
return frameBuffer->format->Bmask;
|
||||
}
|
||||
|
||||
void* CVideo::getAddress()
|
||||
{
|
||||
return frameBuffer->pixels;
|
||||
}
|
||||
|
||||
void CVideo::flip()
|
||||
{
|
||||
::SDL_Flip(frameBuffer);
|
||||
|
|
|
@ -39,7 +39,6 @@ class CVideo {
|
|||
int getBlueMask();
|
||||
|
||||
//functions to access the screen
|
||||
void* getAddress();
|
||||
void lock();
|
||||
void unlock();
|
||||
int mustLock();
|
||||
|
|
|
@ -163,8 +163,10 @@ bool button::hit(int x, int y) const
|
|||
x -= x_;
|
||||
y -= y_;
|
||||
int row_width = image_->w + is_odd(image_->w);
|
||||
|
||||
surface_lock lock(image_);
|
||||
|
||||
if(*(reinterpret_cast<short*>(image_->pixels)+y*row_width+x) != 0)
|
||||
if(*(lock.pixels()+y*row_width+x) != 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ void slider::draw()
|
|||
|
||||
SDL_BlitSurface(buffer_,NULL,screen,&area_);
|
||||
|
||||
display::Pixel* const pixels =
|
||||
reinterpret_cast<display::Pixel*>(screen->pixels);
|
||||
surface_lock screen_lock(screen);
|
||||
display::Pixel* const pixels = screen_lock.pixels();
|
||||
display::Pixel* const line_dest = pixels + screen->w*(area_.y+area_.h/3) +
|
||||
area_.x + hpadding;
|
||||
std::fill(line_dest,line_dest+area_.w-hpadding*2,0xFFFF);
|
||||
|
|
|
@ -56,9 +56,8 @@ void textbox::draw_cursor(int pos) const
|
|||
static const short cursor_colour = 0xFFFF;
|
||||
|
||||
if(show_cursor) {
|
||||
short* dst = reinterpret_cast<short*>(
|
||||
disp_.video().getSurface()->pixels) + y_*disp_.x() +
|
||||
x_ + pos;
|
||||
surface_lock lock(disp_.video().getSurface());
|
||||
short* dst = lock.pixels() + y_*disp_.x() + x_ + pos;
|
||||
|
||||
for(int i = 0; i != height(); ++i, dst += disp_.x()) {
|
||||
*dst = cursor_colour;
|
||||
|
|
Loading…
Add table
Reference in a new issue