Permalink
Browse files

If required, lock the main video surface while blitting (this enables…

… to call 'sdl.Surface.Blit' from one goroutine and 'sdl.SetVideoMode' from another goroutine, while the two goroutines are allowed to execute in parallel, without requiring a mutex in the two goroutines)
  • Loading branch information...
1 parent 58be877 commit aebe60ff9bf2a67587112a6303ea628af4e62399 committed Feb 21, 2011
Showing with 28 additions and 11 deletions.
  1. +28 −11 sdl/sdl.go
View
39 sdl/sdl.go
@@ -422,18 +422,35 @@ func (screen *Surface) Unlock() {
}
func (dst *Surface) Blit(dstrect *Rect, src *Surface, srcrect *Rect) int {
- src.mutex.RLock()
- dst.mutex.Lock()
-
- var ret = C.SDL_UpperBlit(
- src.cSurface,
- (*C.SDL_Rect)(cast(srcrect)),
- dst.cSurface,
- (*C.SDL_Rect)(cast(dstrect)))
-
- dst.mutex.Unlock()
- src.mutex.RUnlock()
+ GlobalMutex.Lock()
+ global := true
+ if (src != currentVideoSurface) && (dst != currentVideoSurface) {
+ GlobalMutex.Unlock()
+ global = false
+ }
+
+ // At this point: GlobalMutex is locked only if at least one of 'src' or 'dst'
+ // was identical to 'currentVideoSurface'
+
+ var ret C.int
+ {
+ src.mutex.RLock()
+ dst.mutex.Lock()
+
+ ret = C.SDL_UpperBlit(
+ src.cSurface,
+ (*C.SDL_Rect)(cast(srcrect)),
+ dst.cSurface,
+ (*C.SDL_Rect)(cast(dstrect)))
+
+ dst.mutex.Unlock()
+ src.mutex.RUnlock()
+ }
+ if global {
+ GlobalMutex.Unlock()
+ }
+
return int(ret)
}

0 comments on commit aebe60f

Please sign in to comment.