summaryrefslogtreecommitdiff
path: root/prenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'prenderer.cpp')
-rw-r--r--prenderer.cpp665
1 files changed, 244 insertions, 421 deletions
diff --git a/prenderer.cpp b/prenderer.cpp
index 58e1b22..aa44a5a 100644
--- a/prenderer.cpp
+++ b/prenderer.cpp
@@ -30,9 +30,9 @@ T_CompPosToLayerPos(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uin
static v2
Transform_ScreenSpaceToLocal(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight,
- ui UI, ImVec2 ViewportMin, ImVec2 Point)
+ ImVec2 CompPos, ImVec2 CompZoom, ImVec2 ViewportMin, ImVec2 Point)
{
- v2 CompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI.CompPos, UI.CompZoom, Point);
+ v2 CompUV = ImGui_ScreenPointToCompUV(ViewportMin, CompPos, CompZoom, Point);
v2 LayerUV = T_CompUVToLayerUV(T, FileWidth, FileHeight, SourceWidth, SourceHeight, CompUV);
return V2(LayerUV.x * SourceWidth, LayerUV.y * SourceHeight);
}
@@ -260,7 +260,26 @@ Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegio
static void
RenderLayers(render_entry Entry) {
- Fallback_RenderLayer(*(transform_info *)Entry.RenderData, Entry.OutputBuffer, Entry.RenderRegion);
+ switch (Entry.RenderType)
+ {
+ case render_type_main:
+ {
+ Fallback_RenderLayer(*(transform_info *)Entry.RenderData, Entry.OutputBuffer, Entry.RenderRegion);
+ } break;
+ case render_type_direct:
+ {
+ Assert(0);
+ // Fallback_RenderDirect(*(direct_info *)Entry.RenderData, Entry.OutputBuffer, Entry.RenderRegion);
+ } break;
+ case render_type_brush:
+ {
+ PaintTest_AVX2(*(brush_info *)Entry.RenderData, Entry.OutputBuffer, Entry.RenderRegion);
+ } break;
+ default:
+ {
+ Assert(0);
+ }
+ }
#if 0
#if ARM
Fallback_RenderLayer(RenderData->TransformInfo[i], RenderInfo->CompBuffer, RenderRegion);
@@ -274,17 +293,17 @@ RenderLayers(render_entry Entry) {
}
static void
-Renderer_Start(void *Data, void *OutputBuffer, rectangle RenderRegion)
+Renderer_Start(void *Data, void *OutputBuffer, render_type RenderType, rectangle RenderRegion)
{
// CPU
- Threading_BitmapOp(Data, OutputBuffer, RenderRegion);
+ Threading_BitmapOp(Data, OutputBuffer, RenderType, RenderRegion);
}
static void
-Renderer_Check(bool32 *Test)
+Renderer_Check(bool32 *Test, render_type RenderType)
{
// CPU
- *Test = Threading_IsActive();
+ *Test = Threading_IsActive(RenderType);
}
@@ -351,7 +370,6 @@ Transform_Calculate(project_state *State, memory *Memory, project_data *File, bl
if (Points[i].x > MaxX) { MaxX = Points[i].x; }
if (Points[i].y > MaxY) { MaxY = Points[i].y; }
}
-
TransformInfo.XAxisPX = XLengthSq*XAxis.x;
TransformInfo.XAxisPY = XLengthSq*XAxis.y;
TransformInfo.YAxisPX = YLengthSq*YAxis.x;
@@ -373,15 +391,137 @@ Transform_Calculate(project_state *State, memory *Memory, project_data *File, bl
TransformInfo.OriginY = Origin.y;
TransformInfo.BufferPitch = Comp->Width*Comp->BytesPerPixel;
TransformInfo.LayerPitch = Width*BytesPerPixel;
- TransformInfo.ClipRect = {MinX - (MinX & 3), MinY, MaxX + 1, MaxY + 1};
+ TransformInfo.ClipRect = {MinX, MinY, MaxX, MaxY};
TransformInfo.IsAdjustment = Layer->IsAdjustment;
return TransformInfo;
}
+// NOTE(fox): is this too ridiculous? i don't trust inline
+#define Fallback_Blend() \
+ switch (T.BlendMode)\
+ {\
+ case blend_normal:\
+ {\
+ } break;\
+ case blend_multiply:\
+ {\
+ R_Blend = R_Dest * R_Col;\
+ G_Blend = G_Dest * G_Col;\
+ B_Blend = B_Dest * B_Col;\
+ } break;\
+ case blend_colorburn:\
+ {\
+ /* NOTE(fox): Padding to prevent actual crashing from zero division */ \
+ R_Blend = 1.0f - ((1.0f - R_Dest) / (R_Col + 0.001f));\
+ G_Blend = 1.0f - ((1.0f - G_Dest) / (G_Col + 0.001f));\
+ B_Blend = 1.0f - ((1.0f - B_Dest) / (B_Col + 0.001f));\
+ } break;\
+ case blend_linearburn:\
+ {\
+ R_Blend = (R_Dest + R_Col) - 1.0f;\
+ G_Blend = (G_Dest + G_Col) - 1.0f;\
+ B_Blend = (B_Dest + B_Col) - 1.0f;\
+ } break;\
+ case blend_add:\
+ {\
+ R_Blend = R_Dest + R_Col;\
+ G_Blend = G_Dest + G_Col;\
+ B_Blend = B_Dest + B_Col;\
+ } break;\
+ case blend_screen:\
+ {\
+ R_Blend = 1.0f - ((1.0f - R_Dest) * (1.0f - R_Col));\
+ G_Blend = 1.0f - ((1.0f - G_Dest) * (1.0f - G_Col));\
+ B_Blend = 1.0f - ((1.0f - B_Dest) * (1.0f - B_Col));\
+ } break;\
+ case blend_overlay:\
+ {\
+ if (R_Dest < 0.5) {\
+ R_Blend = 2.0f * R_Dest * R_Col;\
+ } else {\
+ R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));\
+ }\
+ if (G_Dest < 0.5) {\
+ G_Blend = 2.0f * G_Dest * G_Col;\
+ } else {\
+ G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));\
+ }\
+ if (B_Dest < 0.5) {\
+ B_Blend = 2.0f * B_Dest * B_Col;\
+ } else {\
+ B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));\
+ }\
+ } break;\
+ case blend_softlight:\
+ {\
+ /* using Pegtop's equation */ \
+ R_Blend = ((1.0f - R_Col * 2) * R_Dest * R_Dest) + (R_Col * 2 * R_Dest);\
+ G_Blend = ((1.0f - G_Col * 2) * G_Dest * G_Dest) + (G_Col * 2 * G_Dest);\
+ B_Blend = ((1.0f - B_Col * 2) * B_Dest * B_Dest) + (B_Col * 2 * B_Dest);\
+ } break;\
+ case blend_hardlight:\
+ {\
+ if (R_Dest > 0.5) {\
+ R_Blend = 2.0f * R_Dest * R_Col;\
+ } else {\
+ R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));\
+ }\
+ if (G_Dest > 0.5) {\
+ G_Blend = 2.0f * G_Dest * G_Col;\
+ } else {\
+ G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));\
+ }\
+ if (B_Dest > 0.5) {\
+ B_Blend = 2.0f * B_Dest * B_Col;\
+ } else {\
+ B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));\
+ }\
+ } break;\
+ case blend_subtract:\
+ {\
+ R_Blend = R_Dest - R_Col;\
+ G_Blend = G_Dest - G_Col;\
+ B_Blend = B_Dest - B_Col;\
+ } break;\
+ case blend_divide:\
+ {\
+ R_Blend = R_Dest / (R_Col + 0.001f);\
+ G_Blend = G_Dest / (G_Col + 0.001f);\
+ B_Blend = B_Dest / (B_Col + 0.001f);\
+ } break;\
+ case blend_difference:\
+ {\
+ if (R_Col - R_Dest > 0) {\
+ R_Blend = R_Col - R_Dest;\
+ } else {\
+ R_Blend = R_Dest - R_Col;\
+ }\
+ if (G_Col - G_Dest > 0) {\
+ G_Blend = G_Col - G_Dest;\
+ } else {\
+ G_Blend = G_Dest - G_Col;\
+ }\
+ if (B_Col - B_Dest > 0) {\
+ B_Blend = B_Col - B_Dest;\
+ } else {\
+ B_Blend = B_Dest - B_Col;\
+ }\
+ } break;\
+ }\
+\
+ R_Blend = (R_Dest * (1.0f - LayerAlpha)) + (R_Blend * LayerAlpha);\
+ G_Blend = (G_Dest * (1.0f - LayerAlpha)) + (G_Blend * LayerAlpha);\
+ B_Blend = (B_Dest * (1.0f - LayerAlpha)) + (B_Blend * LayerAlpha);\
+\
+ if (T.BlendMode == blend_normal)\
+ A_Blend = A_Dest + LayerAlpha;\
+ else\
+ A_Blend = A_Dest;\
+
static void
-Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegion)
+Fallback_RenderDirect(transform_info T, void *OutputBuffer, rectangle RenderRegion)
{
rectangle LayerBounds = ClipRectangle( T.ClipRect, RenderRegion);
@@ -390,15 +530,84 @@ Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegio
for (int16 Y = LayerBounds.Min.y; Y < LayerBounds.Max.y; Y++)
{
- real32 StartVectorY = (real32)Y - T.OriginY;
-
for (int16 X = LayerBounds.Min.x; X < LayerBounds.Max.x; X++)
{
+ uint16 LX = X;
+ uint16 LY = Y;
+ uint16 LXPlus = Ceil(X+1, (uint32)T.LayerWidth - 1);
+ uint16 LYPlus = Ceil(Y+1, (uint32)T.LayerHeight - 1);
+
+ uint8 *TexPTR0 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LY) + (LX * (uint16)T.LayerBytesPerPixel));
+ uint32 PixelA = *(uint32 *)TexPTR0;
+
+ real32 TexRA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+
+ real32 LayerAlpha = TexAA * 1; // brush opacity
+
+ real32 R_Col = TexRA;
+ real32 G_Col = TexGA;
+ real32 B_Col = TexBA;
+ real32 A_Col = TexAA;
+
+ real32 R_Blend = TexRA;
+ real32 G_Blend = TexGA;
+ real32 B_Blend = TexBA;
+ real32 A_Blend = TexAA;
+
+ uint8 *DestPixel =((uint8 *)OutputBuffer + ((uint16)Y * (uint16)T.BufferPitch) + ((uint16)X * (uint16)T.BufferBytesPerPixel));
+
+ uint32 *R_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 0);
+ uint32 *G_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 1);
+ uint32 *B_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 2);
+ uint32 *A_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 3);
+
+ if (LayerAlpha != 1.0f || T.BlendMode != blend_normal) {
+
+ real32 R_Dest = (real32)(*R_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+ real32 G_Dest = (real32)(*G_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+ real32 B_Dest = (real32)(*B_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+ real32 A_Dest = (real32)(*A_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+
+ Fallback_Blend();
+ }
+
+ uint32 R_Out = (uint32)(Normalize(R_Blend) * T.BufferBits.Bits);
+ uint32 G_Out = (uint32)(Normalize(G_Blend) * T.BufferBits.Bits);
+ uint32 B_Out = (uint32)(Normalize(B_Blend) * T.BufferBits.Bits);
+ uint32 A_Out = (uint32)(Normalize(A_Blend) * T.BufferBits.Bits);
+
+ *R_DestAddress = (*R_DestAddress & ~T.BufferBits.MaskPixel) | R_Out;
+ *G_DestAddress = (*G_DestAddress & ~T.BufferBits.MaskPixel) | G_Out;
+ *B_DestAddress = (*B_DestAddress & ~T.BufferBits.MaskPixel) | B_Out;
+ *A_DestAddress = (*A_DestAddress & ~T.BufferBits.MaskPixel) | A_Out;
+ }
+ }
+}
+static void
+Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegion)
+{
+ rectangle LayerBounds = ClipRectangle( T.ClipRect, RenderRegion);
+
+ Assert(LayerBounds.Max.x <= T.BufferWidth);
+ Assert(LayerBounds.Max.y <= T.BufferHeight);
+
+ for (int Y = LayerBounds.Min.y; Y < LayerBounds.Max.y; Y++)
+ {
+ real32 StartVectorY = (real32)Y - T.OriginY;
+
+ for (int X = LayerBounds.Min.x; X < LayerBounds.Max.x; X++)
+ {
real32 StartVectorX = X - T.OriginX;
real32 U = (StartVectorX * T.XAxisPX) + (StartVectorY * T.XAxisPY);
real32 V = (StartVectorX * T.YAxisPX) + (StartVectorY * T.YAxisPY);
+ if (X == T.BufferWidth)
+ int why = 0;
+
if (U < 1.0f && U >= 0.0f && V < 1.0f && V >= 0.0f) {
real32 TexXFull = U * T.LayerWidth;
@@ -418,15 +627,15 @@ Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegio
uint32 XLookup, YLookup, PixelToSeek;
- uint16 LX = TexXInt;
- uint16 LY = TexYInt;
- uint16 LXPlus = Ceil(TexXInt+1, (uint32)T.LayerWidth - 1);
- uint16 LYPlus = Ceil(TexYInt+1, (uint32)T.LayerHeight - 1);
+ uint32 LX = TexXInt;
+ uint32 LY = TexYInt;
+ uint32 LXPlus = Ceil(TexXInt+1, (uint32)T.LayerWidth - 1);
+ uint32 LYPlus = Ceil(TexYInt+1, (uint32)T.LayerHeight - 1);
- uint8 *TexPTR0 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LY) + (LX * (uint16)T.LayerBytesPerPixel));
- uint8 *TexPTR1 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LY) + (LXPlus * (uint16)T.LayerBytesPerPixel));
- uint8 *TexPTR2 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LYPlus) + (LX * (uint16)T.LayerBytesPerPixel));
- uint8 *TexPTR3 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LYPlus) + (LXPlus * (uint16)T.LayerBytesPerPixel));
+ uint8 *TexPTR0 = ((uint8 *)T.SourceBuffer + ((uint32)T.LayerPitch * LY) + (LX * (uint32)T.LayerBytesPerPixel));
+ uint8 *TexPTR1 = ((uint8 *)T.SourceBuffer + ((uint32)T.LayerPitch * LY) + (LXPlus * (uint32)T.LayerBytesPerPixel));
+ uint8 *TexPTR2 = ((uint8 *)T.SourceBuffer + ((uint32)T.LayerPitch * LYPlus) + (LX * (uint32)T.LayerBytesPerPixel));
+ uint8 *TexPTR3 = ((uint8 *)T.SourceBuffer + ((uint32)T.LayerPitch * LYPlus) + (LXPlus * (uint32)T.LayerBytesPerPixel));
uint32 PixelA = *(uint32 *)TexPTR0;
uint32 PixelB = *(uint32 *)TexPTR1;
@@ -515,12 +724,13 @@ Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegio
real32 B_Blend = B_Col;
real32 A_Blend = A_Col;
- uint8 *DestPixel =((uint8 *)OutputBuffer + ((uint16)Y * (uint16)T.BufferPitch) + ((uint16)X * (uint16)T.BufferBytesPerPixel));
+ uint8 *DestPixel =((uint8 *)OutputBuffer + ((uint32)Y * (uint32)T.BufferPitch) + ((uint32)X * (uint32)T.BufferBytesPerPixel));
+ Assert(X != (T.BufferWidth));
- uint32 *R_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 0);
- uint32 *G_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 1);
- uint32 *B_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 2);
- uint32 *A_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 3);
+ uint8 *R_DestAddress = (DestPixel + T.BufferBits.ByteOffset * 0);
+ uint8 *G_DestAddress = (DestPixel + T.BufferBits.ByteOffset * 1);
+ uint8 *B_DestAddress = (DestPixel + T.BufferBits.ByteOffset * 2);
+ uint8 *A_DestAddress = (DestPixel + T.BufferBits.ByteOffset * 3);
if (LayerAlpha != 1.0f || T.BlendMode != blend_normal) {
@@ -529,136 +739,18 @@ Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegio
real32 B_Dest = (real32)(*B_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
real32 A_Dest = (real32)(*A_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
- switch (T.BlendMode)
- {
- case blend_normal:
- {
- } break;
- case blend_multiply:
- {
- R_Blend = R_Dest * R_Col;
- G_Blend = G_Dest * G_Col;
- B_Blend = B_Dest * B_Col;
- } break;
- case blend_colorburn:
- {
- // NOTE(fox): Padding to prevent actual crashing from zero division
- R_Blend = 1.0f - ((1.0f - R_Dest) / (R_Col + 0.001f));
- G_Blend = 1.0f - ((1.0f - G_Dest) / (G_Col + 0.001f));
- B_Blend = 1.0f - ((1.0f - B_Dest) / (B_Col + 0.001f));
- } break;
- case blend_linearburn:
- {
- R_Blend = (R_Dest + R_Col) - 1.0f;
- G_Blend = (G_Dest + G_Col) - 1.0f;
- B_Blend = (B_Dest + B_Col) - 1.0f;
- } break;
- case blend_add:
- {
- R_Blend = R_Dest + R_Col;
- G_Blend = G_Dest + G_Col;
- B_Blend = B_Dest + B_Col;
- } break;
- case blend_screen:
- {
- R_Blend = 1.0f - ((1.0f - R_Dest) * (1.0f - R_Col));
- G_Blend = 1.0f - ((1.0f - G_Dest) * (1.0f - G_Col));
- B_Blend = 1.0f - ((1.0f - B_Dest) * (1.0f - B_Col));
- } break;
- case blend_overlay:
- {
- if (R_Dest < 0.5) {
- R_Blend = 2.0f * R_Dest * R_Col;
- } else {
- R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));
- }
- if (G_Dest < 0.5) {
- G_Blend = 2.0f * G_Dest * G_Col;
- } else {
- G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));
- }
- if (B_Dest < 0.5) {
- B_Blend = 2.0f * B_Dest * B_Col;
- } else {
- B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));
- }
- } break;
- case blend_softlight:
- {
- // using Pegtop's equation
- R_Blend = ((1.0f - R_Col * 2) * R_Dest * R_Dest) + (R_Col * 2 * R_Dest);
- G_Blend = ((1.0f - G_Col * 2) * G_Dest * G_Dest) + (G_Col * 2 * G_Dest);
- B_Blend = ((1.0f - B_Col * 2) * B_Dest * B_Dest) + (B_Col * 2 * B_Dest);
- } break;
- case blend_hardlight:
- {
- if (R_Dest > 0.5) {
- R_Blend = 2.0f * R_Dest * R_Col;
- } else {
- R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));
- }
- if (G_Dest > 0.5) {
- G_Blend = 2.0f * G_Dest * G_Col;
- } else {
- G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));
- }
- if (B_Dest > 0.5) {
- B_Blend = 2.0f * B_Dest * B_Col;
- } else {
- B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));
- }
- } break;
- case blend_subtract:
- {
- R_Blend = R_Dest - R_Col;
- G_Blend = G_Dest - G_Col;
- B_Blend = B_Dest - B_Col;
- } break;
- case blend_divide:
- {
- R_Blend = R_Dest / (R_Col + 0.001f);
- G_Blend = G_Dest / (G_Col + 0.001f);
- B_Blend = B_Dest / (B_Col + 0.001f);
- } break;
- case blend_difference:
- {
- if (R_Col - R_Dest > 0) {
- R_Blend = R_Col - R_Dest;
- } else {
- R_Blend = R_Dest - R_Col;
- }
- if (G_Col - G_Dest > 0) {
- G_Blend = G_Col - G_Dest;
- } else {
- G_Blend = G_Dest - G_Col;
- }
- if (B_Col - B_Dest > 0) {
- B_Blend = B_Col - B_Dest;
- } else {
- B_Blend = B_Dest - B_Col;
- }
- } break;
- }
-
- R_Blend = (R_Dest * (1.0f - LayerAlpha)) + (R_Blend * LayerAlpha);
- G_Blend = (G_Dest * (1.0f - LayerAlpha)) + (G_Blend * LayerAlpha);
- B_Blend = (B_Dest * (1.0f - LayerAlpha)) + (B_Blend * LayerAlpha);
-
- if (T.BlendMode == blend_normal)
- A_Blend = A_Dest + LayerAlpha;
- else
- A_Blend = A_Dest;
+ Fallback_Blend();
}
- uint32 R_Out = (uint32)(Normalize(R_Blend) * T.BufferBits.Bits);
- uint32 G_Out = (uint32)(Normalize(G_Blend) * T.BufferBits.Bits);
- uint32 B_Out = (uint32)(Normalize(B_Blend) * T.BufferBits.Bits);
- uint32 A_Out = (uint32)(Normalize(A_Blend) * T.BufferBits.Bits);
+ uint8 R_Out = (uint8)(Normalize(R_Blend) * T.BufferBits.Bits);
+ uint8 G_Out = (uint8)(Normalize(G_Blend) * T.BufferBits.Bits);
+ uint8 B_Out = (uint8)(Normalize(B_Blend) * T.BufferBits.Bits);
+ uint8 A_Out = (uint8)(Normalize(A_Blend) * T.BufferBits.Bits);
- *R_DestAddress = (*R_DestAddress & ~T.BufferBits.MaskPixel) | R_Out;
- *G_DestAddress = (*G_DestAddress & ~T.BufferBits.MaskPixel) | G_Out;
- *B_DestAddress = (*B_DestAddress & ~T.BufferBits.MaskPixel) | B_Out;
- *A_DestAddress = (*A_DestAddress & ~T.BufferBits.MaskPixel) | A_Out;
+ *R_DestAddress = R_Out;
+ *G_DestAddress = G_Out;
+ *B_DestAddress = B_Out;
+ *A_DestAddress = A_Out;
// *R_DestAddress = 255;
// *G_DestAddress = 255;
// *B_DestAddress = 255;
@@ -1781,274 +1873,5 @@ SSE2_RenderLayer(transform_info T, comp_buffer *Buffer, rectangle RenderRegion)
}
}
-
-#endif
-
-static void
-Fallback_RenderLayer(transform_info T, comp_buffer *Buffer, rectangle RenderRegion)
-{
- rectangle LayerBounds = ClipRectangle( T.ClipRect, RenderRegion);
-
- Assert(LayerBounds.Max.x <= Buffer->Width);
- Assert(LayerBounds.Max.y <= Buffer->Height);
-
- uint16 WidthP, HeightP;
- Bitmap_CalcPackedDimensions(Buffer->Width, Buffer->Height, &WidthP, &HeightP);
-
- real32 Normalized255 = 1 / 255.0f;
-
- for (int16 Y = LayerBounds.Min.y; Y < LayerBounds.Max.y; Y++)
- {
- real32 StartVectorY = (real32)Y - T.OriginY;
-
- for (int16 X = LayerBounds.Min.x; X < LayerBounds.Max.x; X++)
- {
-
- real32 StartVectorX = X - T.OriginX;
- real32 U = (StartVectorX * T.XAxisPX) + (StartVectorY * T.XAxisPY);
- real32 V = (StartVectorX * T.YAxisPX) + (StartVectorY * T.YAxisPY);
-
- if (U < 1.0f && U >= 0.0f && V < 1.0f && V >= 0.0f) {
-
- real32 TexXFull = U * T.LayerWidth;
- uint32 TexXInt = (uint32)TexXFull;
- real32 TexX = TexXFull - TexXInt;
-
- real32 TexYFull = V * T.LayerHeight;
- uint32 TexYInt = (uint32)TexYFull;
- real32 TexY = TexYFull - TexYInt;
-
- real32 TexXInv = 1 - TexX;
- real32 TexYInv = 1 - TexY;
- real32 TexBothXInv = TexXInv * TexY;
- real32 TexBothYInv = TexX * TexYInv;
- real32 TexBoth = TexY * TexX;
- real32 TexBothInv = TexXInv * TexYInv;
-
- uint32 XLookup, YLookup, PixelToSeek;
-
- uint16 LX = TexXInt;
- uint16 LY = TexYInt;
- uint16 LXPlus = Ceil(TexXInt+1, (uint32)T.LayerWidth - 1);
- uint16 LYPlus = Ceil(TexYInt+1, (uint32)T.LayerHeight - 1);
-
-#if PACKEDRGB
- // TODO(fox): Be careful with the BytesPerPixel here! It's the
- // buffer's, not the layer's (currently everything is 4 bytes
- // per pixel).
- XLookup = (LX >> 2)*16 + (LX % 4);
- YLookup = (LY >> 2)*(T.FullLayerWidth*4) + (LY % 4)*4;
- PixelToSeek = XLookup + YLookup;
- uint32 PixelA = *(uint32 *)((uint8 *)T.SourceBuffer + PixelToSeek*Buffer->BytesPerPixel);
-
- XLookup = (LXPlus >> 2)*16 + (LXPlus % 4);
- YLookup = (LY >> 2)*(T.FullLayerWidth*4) + (LY % 4)*4;
- PixelToSeek = XLookup + YLookup;
- uint32 PixelB = *(uint32 *)((uint8 *)T.SourceBuffer + PixelToSeek*Buffer->BytesPerPixel);
-
- XLookup = (LX >> 2)*16 + (LX % 4);
- YLookup = (LYPlus >> 2)*(T.FullLayerWidth*4) + (LYPlus % 4)*4;
- PixelToSeek = XLookup + YLookup;
- uint32 PixelC = *(uint32 *)((uint8 *)T.SourceBuffer + PixelToSeek*Buffer->BytesPerPixel);
-
- XLookup = (LXPlus >> 2)*16 + (LXPlus % 4);
- YLookup = (LYPlus >> 2)*(T.FullLayerWidth*4) + (LYPlus % 4)*4;
- PixelToSeek = XLookup + YLookup;
- uint32 PixelD = *(uint32 *)((uint8 *)T.SourceBuffer + PixelToSeek*Buffer->BytesPerPixel);
-
- XLookup = (X >> 2)*16 + (X % 4);
- YLookup = (Y >> 2)*(WidthP*4) + (Y % 4)*4;
- PixelToSeek = XLookup + YLookup;
- uint32 *Pixel = (uint32 *)((uint8 *)Buffer->PackedBuffer + PixelToSeek*Buffer->BytesPerPixel);
-
-#else
- uint8 *TexPTR0 = ((uint8 *)T.SourceBuffer + (uint16)T.LayerPitch*LY + LX*Buffer->BytesPerPixel);
- uint8 *TexPTR1 = ((uint8 *)T.SourceBuffer + (uint16)T.LayerPitch*LY + LXPlus*Buffer->BytesPerPixel);
- uint8 *TexPTR2 = ((uint8 *)T.SourceBuffer + (uint16)T.LayerPitch*LYPlus + LX*Buffer->BytesPerPixel);
- uint8 *TexPTR3 = ((uint8 *)T.SourceBuffer + (uint16)T.LayerPitch*LYPlus + LXPlus*Buffer->BytesPerPixel);
-
- uint32 PixelA = *(uint32 *)TexPTR0;
- uint32 PixelB = *(uint32 *)TexPTR1;
- uint32 PixelC = *(uint32 *)TexPTR2;
- uint32 PixelD = *(uint32 *)TexPTR3;
-
- uint32 *Pixel = (uint32 *)((uint8 *)Buffer->UnpackedBuffer + Y*T.BufferPitch + X*Buffer->BytesPerPixel);
#endif
- real32 TexRA = (real32)(PixelA & 0xFF) * Normalized255;
- real32 TexRB = (real32)(PixelB & 0xFF) * Normalized255;
- real32 TexRC = (real32)(PixelC & 0xFF) * Normalized255;
- real32 TexRD = (real32)(PixelD & 0xFF) * Normalized255;
-
- real32 TexGA = (real32)((PixelA >> 8) & 0xFF) * Normalized255;
- real32 TexGB = (real32)((PixelB >> 8) & 0xFF) * Normalized255;
- real32 TexGC = (real32)((PixelC >> 8) & 0xFF) * Normalized255;
- real32 TexGD = (real32)((PixelD >> 8) & 0xFF) * Normalized255;
-
- real32 TexBA = (real32)((PixelA >> 16) & 0xFF) * Normalized255;
- real32 TexBB = (real32)((PixelB >> 16) & 0xFF) * Normalized255;
- real32 TexBC = (real32)((PixelC >> 16) & 0xFF) * Normalized255;
- real32 TexBD = (real32)((PixelD >> 16) & 0xFF) * Normalized255;
-
- real32 TexAA = (real32)((PixelA >> 24) & 0xFF) * Normalized255;
- real32 TexAB = (real32)((PixelB >> 24) & 0xFF) * Normalized255;
- real32 TexAC = (real32)((PixelC >> 24) & 0xFF) * Normalized255;
- real32 TexAD = (real32)((PixelD >> 24) & 0xFF) * Normalized255;
-
- real32 R_Col = (TexBothInv * TexRA) + (TexBothYInv * TexRB)
- + (TexBothXInv * TexRC) + (TexBoth * TexRD);
- real32 G_Col = (TexBothInv * TexGA) + (TexBothYInv * TexGB)
- + (TexBothXInv * TexGC) + (TexBoth * TexGD);
- real32 B_Col = (TexBothInv * TexBA) + (TexBothYInv * TexBB)
- + (TexBothXInv * TexBC) + (TexBoth * TexBD);
- real32 A_Col = (TexBothInv * TexAA) + (TexBothYInv * TexAB)
- + (TexBothXInv * TexAC) + (TexBoth * TexAD);
-
- real32 LayerAlpha = A_Col * T.LayerOpacity;
-
- real32 R_Blend = R_Col;
- real32 G_Blend = G_Col;
- real32 B_Blend = B_Col;
- real32 A_Blend = A_Col;
-
- if (LayerAlpha != 1.0f || T.BlendMode != blend_normal) {
-
- real32 R_Dest = (real32)((*Pixel >> 0) & 0xFF) * Normalized255;
- real32 G_Dest = (real32)((*Pixel >> 8) & 0xFF) * Normalized255;
- real32 B_Dest = (real32)((*Pixel >> 16) & 0xFF) * Normalized255;
- real32 A_Dest = (real32)((*Pixel >> 24) & 0xFF) * Normalized255;
-
- switch (T.BlendMode)
- {
- case blend_normal:
- {
- } break;
- case blend_multiply:
- {
- R_Blend = R_Dest * R_Col;
- G_Blend = G_Dest * G_Col;
- B_Blend = B_Dest * B_Col;
- } break;
- case blend_colorburn:
- {
- // NOTE(fox): Padding to prevent actual crashing from zero division
- R_Blend = 1.0f - ((1.0f - R_Dest) / (R_Col + 0.001f));
- G_Blend = 1.0f - ((1.0f - G_Dest) / (G_Col + 0.001f));
- B_Blend = 1.0f - ((1.0f - B_Dest) / (B_Col + 0.001f));
- } break;
- case blend_linearburn:
- {
- R_Blend = (R_Dest + R_Col) - 1.0f;
- G_Blend = (G_Dest + G_Col) - 1.0f;
- B_Blend = (B_Dest + B_Col) - 1.0f;
- } break;
- case blend_add:
- {
- R_Blend = R_Dest + R_Col;
- G_Blend = G_Dest + G_Col;
- B_Blend = B_Dest + B_Col;
- } break;
- case blend_screen:
- {
- R_Blend = 1.0f - ((1.0f - R_Dest) * (1.0f - R_Col));
- G_Blend = 1.0f - ((1.0f - G_Dest) * (1.0f - G_Col));
- B_Blend = 1.0f - ((1.0f - B_Dest) * (1.0f - B_Col));
- } break;
- case blend_overlay:
- {
- if (R_Dest < 0.5) {
- R_Blend = 2.0f * R_Dest * R_Col;
- } else {
- R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));
- }
- if (G_Dest < 0.5) {
- G_Blend = 2.0f * G_Dest * G_Col;
- } else {
- G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));
- }
- if (B_Dest < 0.5) {
- B_Blend = 2.0f * B_Dest * B_Col;
- } else {
- B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));
- }
- } break;
- case blend_softlight:
- {
- // using Pegtop's equation
- R_Blend = ((1.0f - R_Col * 2) * R_Dest * R_Dest) + (R_Col * 2 * R_Dest);
- G_Blend = ((1.0f - G_Col * 2) * G_Dest * G_Dest) + (G_Col * 2 * G_Dest);
- B_Blend = ((1.0f - B_Col * 2) * B_Dest * B_Dest) + (B_Col * 2 * B_Dest);
- } break;
- case blend_hardlight:
- {
- if (R_Dest > 0.5) {
- R_Blend = 2.0f * R_Dest * R_Col;
- } else {
- R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));
- }
- if (G_Dest > 0.5) {
- G_Blend = 2.0f * G_Dest * G_Col;
- } else {
- G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));
- }
- if (B_Dest > 0.5) {
- B_Blend = 2.0f * B_Dest * B_Col;
- } else {
- B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));
- }
- } break;
- case blend_subtract:
- {
- R_Blend = R_Dest - R_Col;
- G_Blend = G_Dest - G_Col;
- B_Blend = B_Dest - B_Col;
- } break;
- case blend_divide:
- {
- R_Blend = R_Dest / (R_Col + 0.001f);
- G_Blend = G_Dest / (G_Col + 0.001f);
- B_Blend = B_Dest / (B_Col + 0.001f);
- } break;
- case blend_difference:
- {
- if (R_Col - R_Dest > 0) {
- R_Blend = R_Col - R_Dest;
- } else {
- R_Blend = R_Dest - R_Col;
- }
- if (G_Col - G_Dest > 0) {
- G_Blend = G_Col - G_Dest;
- } else {
- G_Blend = G_Dest - G_Col;
- }
- if (B_Col - B_Dest > 0) {
- B_Blend = B_Col - B_Dest;
- } else {
- B_Blend = B_Dest - B_Col;
- }
- } break;
- }
-
- R_Blend = (R_Dest * (1.0f - LayerAlpha)) + (R_Blend * LayerAlpha);
- G_Blend = (G_Dest * (1.0f - LayerAlpha)) + (G_Blend * LayerAlpha);
- B_Blend = (B_Dest * (1.0f - LayerAlpha)) + (B_Blend * LayerAlpha);
-
- if (T.BlendMode == blend_normal)
- A_Blend = A_Dest + LayerAlpha;
- else
- A_Blend = A_Dest;
- }
-
- uint8 R_Out = (uint8)(Normalize(R_Blend) * 255.0f);
- uint8 G_Out = (uint8)(Normalize(G_Blend) * 255.0f);
- uint8 B_Out = (uint8)(Normalize(B_Blend) * 255.0f);
- uint8 A_Out = (uint8)(Normalize(A_Blend) * 255.0f);
-
- *Pixel = ((A_Out << 24) |
- (B_Out << 16) |
- (G_Out << 8) |
- (R_Out << 0));
- }
- }
- }
-}
#endif