Skip to content

Commit b33aafc

Browse files
committed
Allocate fillRect in C, not in GC
1 parent 2f85481 commit b33aafc

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

bench/Space.hs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ main =
4848
(\weight ->
4949
if weightGCs weight > 0
5050
then Just "Non-zero number of garbage collections!"
51-
else if weightAllocatedBytes weight > 3000
51+
else if weightAllocatedBytes weight > 4000
5252
then Just
53-
"Allocated >3KB! Allocations should be constant."
53+
"Allocated >4KB! Allocations should be constant."
5454
else Nothing)
5555
| i <- [1, 10, 100, 1000]
5656
]
@@ -62,12 +62,27 @@ main =
6262
(\weight ->
6363
if weightGCs weight > 0
6464
then Just "Non-zero number of garbage collections!"
65-
else if weightAllocatedBytes weight > 3000
65+
else if weightAllocatedBytes weight > 4000
6666
then Just
67-
"Allocated >3KB! Allocations should be constant."
67+
"Allocated >KB! Allocations should be constant."
6868
else Nothing)
6969
| i <- [1, 10, 100, 1000, 2000]
70-
])
70+
]
71+
sequence_
72+
[ validateAction
73+
("pollEvent + drawRect " ++ show i)
74+
pollEventDrawRectTest
75+
i
76+
(\weight ->
77+
if weightGCs weight > 0
78+
then Just "Non-zero number of garbage collections!"
79+
else if weightAllocatedBytes weight > 4000
80+
then Just
81+
"Allocated >4KB! Allocations should be constant."
82+
else Nothing)
83+
| i <- [1, 10, 100, 1000]
84+
]
85+
)
7186

7287
-- | Test that merely polling does not allocate or engage the GC.
7388
-- <https://github.com/haskell-game/sdl2/issues/178>
@@ -101,7 +116,7 @@ pollEventClearTest iters = do
101116
pollEventPresentTest :: Int -> IO ()
102117
pollEventPresentTest iters = do
103118
initializeAll
104-
window <- createWindow "pollEventClearTest" defaultWindow
119+
window <- createWindow "pollEventPresentTest" defaultWindow
105120
renderer <- createRenderer window (-1) defaultRenderer
106121
let go :: Int -> IO ()
107122
go 0 = pure ()
@@ -117,7 +132,7 @@ pollEventPresentTest iters = do
117132
pollEventDrawColorTest :: Int -> IO ()
118133
pollEventDrawColorTest iters = do
119134
initializeAll
120-
window <- createWindow "pollEventClearTest" defaultWindow
135+
window <- createWindow "pollEventDrawColorTest" defaultWindow
121136
renderer <- createRenderer window (-1) defaultRenderer
122137
let go :: Int -> IO ()
123138
go 0 = pure ()
@@ -128,3 +143,21 @@ pollEventDrawColorTest iters = do
128143
present renderer
129144
go (i - 1)
130145
go iters
146+
147+
-- | Draw a rectangle on screen.
148+
pollEventDrawRectTest :: Int -> IO ()
149+
pollEventDrawRectTest iters = do
150+
initializeAll
151+
window <- createWindow "pollEventDrawRectTest" defaultWindow
152+
renderer <- createRenderer window (-1) defaultRenderer
153+
let go :: Int -> IO ()
154+
go 0 = pure ()
155+
go i = do
156+
_ <- pollEvent
157+
rendererDrawColor renderer $= V4 40 40 40 255
158+
clear renderer
159+
rendererDrawColor renderer $= V4 255 255 255 255
160+
fillRect renderer (Just (Rectangle (P (V2 40 40)) (V2 80 80)))
161+
present renderer
162+
go (i - 1)
163+
go iters

cbits/sdlhelper.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,13 @@ int SDLHelper_SetError (const char *str)
7575
{
7676
return SDL_SetError ("%s", str);
7777
}
78+
79+
int SDLHelper_RenderFillRectEx(SDL_Renderer* renderer, int x, int y, int w, int h)
80+
{
81+
SDL_Rect rect;
82+
rect.x=x;
83+
rect.y=y;
84+
rect.w=w;
85+
rect.h=h;
86+
return SDL_RenderFillRect(renderer,&rect);
87+
}

src/SDL/Raw/Video.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ module SDL.Raw.Video (
110110
renderDrawRect,
111111
renderDrawRects,
112112
renderFillRect,
113+
renderFillRectEx,
113114
renderFillRects,
114115
renderGetClipRect,
115116
renderGetLogicalSize,
@@ -315,6 +316,7 @@ foreign import ccall "SDL.h SDL_RenderDrawPoints" renderDrawPointsFFI :: Rendere
315316
foreign import ccall "SDL.h SDL_RenderDrawRect" renderDrawRectFFI :: Renderer -> Ptr Rect -> IO CInt
316317
foreign import ccall "SDL.h SDL_RenderDrawRects" renderDrawRectsFFI :: Renderer -> Ptr Rect -> CInt -> IO CInt
317318
foreign import ccall "SDL.h SDL_RenderFillRect" renderFillRectFFI :: Renderer -> Ptr Rect -> IO CInt
319+
foreign import ccall "sqlhelper.c SDLHelper_RenderFillRectEx" renderFillRectExFFI :: Renderer -> CInt -> CInt -> CInt -> CInt -> IO CInt
318320
foreign import ccall "SDL.h SDL_RenderFillRects" renderFillRectsFFI :: Renderer -> Ptr Rect -> CInt -> IO CInt
319321
foreign import ccall "SDL.h SDL_RenderGetClipRect" renderGetClipRectFFI :: Renderer -> Ptr Rect -> IO ()
320322
foreign import ccall "SDL.h SDL_RenderGetLogicalSize" renderGetLogicalSizeFFI :: Renderer -> Ptr CInt -> Ptr CInt -> IO ()
@@ -822,6 +824,10 @@ renderDrawRects :: MonadIO m => Renderer -> Ptr Rect -> CInt -> m CInt
822824
renderDrawRects v1 v2 v3 = liftIO $ renderDrawRectsFFI v1 v2 v3
823825
{-# INLINE renderDrawRects #-}
824826

827+
renderFillRectEx :: MonadIO m => Renderer -> CInt -> CInt -> CInt -> CInt -> m CInt
828+
renderFillRectEx v1 x y w h = liftIO $ renderFillRectExFFI v1 x y w h
829+
{-# INLINE renderFillRectEx #-}
830+
825831
renderFillRect :: MonadIO m => Renderer -> Ptr Rect -> m CInt
826832
renderFillRect v1 v2 = liftIO $ renderFillRectFFI v1 v2
827833
{-# INLINE renderFillRect #-}

src/SDL/Video/Renderer.hs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE ScopedTypeVariables #-}
12
{-# LANGUAGE CPP #-}
23
{-# LANGUAGE DeriveDataTypeable #-}
34
{-# LANGUAGE DeriveFunctor #-}
@@ -118,6 +119,7 @@ module SDL.Video.Renderer
118119
) where
119120

120121
import Control.Monad.IO.Class (MonadIO, liftIO)
122+
import Control.Exception (catch, throw, SomeException, uninterruptibleMask_)
121123
import Data.Bits
122124
import Data.Data (Data)
123125
import Data.Foldable
@@ -623,15 +625,18 @@ drawRects (Renderer r) rects = liftIO $
623625
-- | Fill a rectangle on the current rendering target with the drawing color.
624626
--
625627
-- See @<https://wiki.libsdl.org/SDL_RenderFillRect SDL_RenderFillRect>@ for C documentation.
626-
fillRect :: MonadIO m
627-
=> Renderer
628-
-> Maybe (Rectangle CInt) -- ^ The rectangle to fill. 'Nothing' for the entire rendering context.
629-
-> m ()
630-
fillRect (Renderer r) rect = liftIO $ do
628+
fillRect ::
629+
MonadIO m
630+
=> Renderer
631+
-> Maybe (Rectangle CInt) -- ^ The rectangle to fill.
632+
-> m ()
633+
fillRect (Renderer r) rect =
634+
liftIO $
631635
throwIfNeg_ "SDL.Video.fillRect" "SDL_RenderFillRect" $
632-
maybeWith with rect $ \rPtr ->
633-
Raw.renderFillRect r
634-
(castPtr rPtr)
636+
case rect of
637+
Nothing -> Raw.renderFillRect r nullPtr
638+
Just (Rectangle (P (V2 x y)) (V2 w h)) -> Raw.renderFillRectEx r x y w h
639+
{-# INLINE fillRect #-}
635640

636641
-- | Fill some number of rectangles on the current rendering target with the drawing color.
637642
--

0 commit comments

Comments
 (0)