#if SPECIAL #include "main.h" #endif static void RenderLayers(render_entry Entry); static bool32 CheckQueue(uint16 Index) { bool32 Result = 0; uint32 Q = SDL_AtomicGet(&QueuedEntries); uint32 C = SDL_AtomicGet(&CurrentEntry); if (Q > C) { if (SDL_AtomicCAS(&CurrentEntry, C, C + 1)) { // printf("C: %i START: F%i Thread %i, region X%i Y%i\n", C, Entry->FrameNumber, Index, Entry->RenderRegion.Min.x, Entry->RenderRegion.Min.y); RenderLayers(Entries[C]); // printf("END: F%i Thread %i, region X%i Y%i\n", Entry->FrameNumber, Index, Entry->RenderRegion.Min.x, Entry->RenderRegion.Min.y); SDL_AtomicAdd(&CompletedEntries, 1); Result = 1; } } return Result; } static int TestThread(void *ptr) { uint16 Index = *(uint16 *)ptr; for(;;) { if (!CheckQueue(Index)) { SDL_SemWait(Semaphore); } } } static bool32 Threading_IsActive(render_type RenderType) { int32 Threads = 16; if (RenderType == render_type_brush) Threads = 4; uint32 C = SDL_AtomicGet(&CompletedEntries); Assert(C < Threads + 1); return (C == Threads) ? false : true; } static void Threading_BitmapOp(void *Data, void *OutputBuffer, render_type RenderType, rectangle InitialRenderRegion) { int i = (RenderType != render_type_brush) ? 4 : 2; uint16 TileWidth = (InitialRenderRegion.Max.x - InitialRenderRegion.Min.x) / i; uint16 TileHeight = (InitialRenderRegion.Max.y - InitialRenderRegion.Min.y) / i; SDL_AtomicSet(&QueuedEntries, 0); SDL_AtomicSet(&CurrentEntry, 0); SDL_AtomicSet(&CompletedEntries, 0); for (int y = 0; y < i; y++) { for (int x = 0; x < i; x++) { // if ((x == 0 && y == 0)|| RenderType != render_type_brush) { rectangle RenderRegion = { TileWidth*x, TileHeight*y, TileWidth + TileWidth*x, TileHeight + TileHeight*y }; if (RenderType != render_type_main) { RenderRegion.Min.x += InitialRenderRegion.Min.x; RenderRegion.Min.y += InitialRenderRegion.Min.y; RenderRegion.Max.x += InitialRenderRegion.Min.x; RenderRegion.Max.y += InitialRenderRegion.Min.y; } if (RenderRegion.Max.x > InitialRenderRegion.Max.x) RenderRegion.Max.x = InitialRenderRegion.Max.x; if (RenderRegion.Max.y > InitialRenderRegion.Max.y) RenderRegion.Max.y = InitialRenderRegion.Max.y; if (x == i-1) RenderRegion.Max.x = InitialRenderRegion.Max.x; if (y == i-1) RenderRegion.Max.y = InitialRenderRegion.Max.y; render_entry Entry = { Data, OutputBuffer, RenderType, RenderRegion }; uint32 Q = SDL_AtomicGet(&QueuedEntries); *(Entries + Q) = Entry; SDL_AtomicAdd(&QueuedEntries, 1); SDL_SemPost(Semaphore); // } } } }