📄 blit_arm_stretch.c
字号:
p->PalPtr = InstCreate32((int)p->LookUp_Data,NONE,NONE,NONE,0,0);
MB(); I1P(LDR,R3,p->PalPtr,0);
if (p->Dither)
{
I2C(MOV,R1,NONE,0);
I2C(MOV,R2,NONE,0);
}
}
else
{
if (p->Dither)
{
I2C(MVN,R1,NONE,0x80000000);
I2C(MVN,R2,NONE,0x80000000);
I2C(MVN,R3,NONE,0x80000000);
}
}
I2C(MOV,R5,NONE,0); //Pos
LoopY = Label(0);
I0P(B,AL,LoopY);
if (p->InvertMask) InstPost(p->InvertMask);
if (p->DiffMask) InstPost(p->DiffMask);
if (p->PalPtr) InstPost(p->PalPtr);
ColCount = 32;
for (i=1;i<16 && !(p->RScaleX & i);i<<=1)
ColCount >>= 1;
InstPost(LoopY);
EndOfLine = Label(0);
//R4 Width
//R5 Pos
//R7 SrcPitch
if (p->SwapXY)
{
I3(MUL,R4,R6,R4); //R6=DstPitch
I3(ADD,R4,R9,R4);
}
else
{
if (p->DirX > 0)
I3S(ADD,R4,R9,R4,LSL,p->DstBPP2);
else
I3S(SUB,R4,R9,R4,LSL,p->DstBPP2);
}
I2C(STR,R4,SP,OFS(stack,EndOfLine));
if (p->SwapXY)
{
//we need next row in R14,R7,R8 (YUV)
IMul(R6,R5,p->RScaleY); //R6 = RScaleY*Pos
I2C(ADD,R8,R6,p->RScaleY);//R8 = RScaleY*(Pos+1)
// dY = ((RScaleY * (Pos+1)) >> 4) - ((RScaleY * Pos) >> 4);
I3S(MOV,R14,NONE,R8,LSR,4);
I3S(SUB,R14,R14,R6,LSR,4);
I3(MUL,R14,R7,R14);
// dUV = ((RScaleY * (Pos+1)) >> (4+SrcUVY2)) - ((RScaleY * Pos) >> (4+SrcUVY2));
I3S(MOV,R8,NONE,R8,LSR,4+p->SrcUVY2);
I3S(SUB,R8,R8,R6,LSR,4+p->SrcUVY2);
I3(MUL,R8,R7,R8);
I3(ADD,R14,R12,R14);
I3S(ADD,R7,R10,R8,ASR,p->SrcUVX2);
I3S(ADD,R8,R11,R8,ASR,p->SrcUVX2);
}
I2C(STR,R5,SP,OFS(stack,Pos));
// special case, when R7,R8 must be saved/restored and incremented separatly
Special = p->OnlyDiff && (p->Dither) && (p->SwapXY);
if (Special)
{
I2C(STR,R7,SP,OFS(stack,SaveR7));
I2C(STR,R8,SP,OFS(stack,SaveR8));
}
if (p->OnlyDiff)
{
MB(); I2C(LDR,R5,SP,OFS(stack,DiffMask));
MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
}
LoopX = Label(1);
RegDirty = 1;
NoInc = 0;
for (Col=0;Col<ColCount;)
{
int x = (Col * p->RScaleX) >> 4;
int IncY;
int IncUV;
int IncY2 = 0;
int IncUV2 = 0;
int Col1 = Col;
int Col2 = Col;
IncY = (((Col+1) * p->RScaleX) >> 4) - ((Col * p->RScaleX) >> 4);
IncUV = (((Col+1) * p->RScaleX) >> (4+p->SrcUVX2)) - ((Col * p->RScaleX) >> (4+p->SrcUVX2));
Col++;
if (!(p->SwapXY))
{
IncY2 = (((Col+1) * p->RScaleX) >> 4) - ((Col * p->RScaleX) >> 4);
IncUV2 = (((Col+1) * p->RScaleX) >> (4+p->SrcUVX2)) - ((Col * p->RScaleX) >> (4+p->SrcUVX2));
Col2++;
Col++;
}
else
if (!p->OnlyDiff)
{
IncY2 = IncY;
IncUV2 = IncUV;
}
if (p->OnlyDiff)
{
reg RC = (reg)(p->SwapXY ? R0 : R14);
reg RA = (reg)(p->Dither ? R7 : R1);
reg RB = (reg)(p->Dither ? R8 : R2);
RegDirty = 1;
p->Skip = Label(0);
//RC,RA,RB,R4 for temporary
//R5(DiffMask),R6(Src2SrcLast)
if (p->SwapXY)
{
Byte(); I3(LDR,RC,R12,R6);
Byte(); I2C(LDR_POST,RA,R12,IncY);
Byte(); I3(LDR,R4,R14,R6);
Byte(); I2C(LDR_POST,RB,R14,IncY);
IncY = IncY2 = -IncY;
}
else
{
Byte(); I3(LDR,RC,R12,R6);
Byte(); I2C(LDR_POST,RA,R12,IncY);
Byte(); I3(LDR,R4,R12,R6);
Byte(); I2C(LDR_POST,RB,R12,IncY2);
IncY = -IncY-IncY2;
IncY2 = -IncY2;
}
I3(EOR,RC,RC,RA);
S(); I3(TST,NONE,RC,R5);
I3(EOR,R4,R4,RB);
C(EQ); S(); I3(TST,NONE,R4,R5);
C(EQ); Byte(); I3(LDR,RC,R10,R6); //last u
Byte(); I2C(LDR_POST,RA,R10,IncUV+IncUV2); //u
C(EQ); Byte(); I3(LDR,R4,R11,R6); //last v
Byte(); I2C(LDR_POST,RB,R11,IncUV+IncUV2); //v
IncUV = -IncUV-IncUV2;
if (Special) //R7,R8 not incremented, using direct position
IncUV2 = x >> p->SrcUVX2;
else
if (p->SwapXY) //IncUV2 will increment R7,R8
{
I2C(ADD,R7,R7,-IncUV);
I2C(ADD,R8,R8,-IncUV);
IncUV2 = IncUV;
}
else
IncUV2 = -IncUV2;
C(EQ); I3(EOR,RC,RC,RA);
C(EQ); S(); I3(TST,NONE,RC,R5);
C(EQ); I3(EOR,R4,R4,RB);
C(EQ); S(); I3(TST,NONE,R4,R5);
C(EQ); I2C(LDR,R4,SP,OFS(stack,EndOfLine));
#ifdef SHOWDIFF
I2C(MVN,RC,NONE,0);
if (DstBPP==8) Half();
C(EQ); I2(STR,RC,R9);
#endif
if (p->SwapXY)
{
MB(); I2C(LDR,RC,SP,OFS(stack,DstPitch));
C(EQ); I3(ADD,R9,R9,RC);
}
else
{
C(EQ); I2C(ADD,R9,R9,p->DstStepX);
}
I0P(B,EQ,p->Skip);
if (Special)
{
I2C(LDR,R7,SP,OFS(stack,SaveR7));
I2C(LDR,R8,SP,OFS(stack,SaveR8));
}
}
p->Upper = p->DirX < 0;
if (ReUse && NoInc)
{
p->Pos = 0;
if (!p->SwapXY && p->DstBPP==16)
I3S(MOV,R0,NONE,R0,LSL,p->Upper?16:-16);
if (!p->OnlyDiff)
Inc_RGB_UV_Pixel(p, IncY, IncUV);
}
else
{
p->Pos = -1;
Stretch_RGB_UV_Pixel(p, Col1, IncY, IncUV);
RegDirty = 1;
}
if (!p->SwapXY)
NoInc = !IncY && !IncUV;
if (p->DstPalette)
Byte();
if (p->DstPalette || p->DstBPP==32)
{
if (p->DstBPP==32 && p->Pos)
I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
if (p->SwapXY)
I2C(STR,R0,R9,-p->DstStepX/2);
else
I2C(STR_POST,R0,R9,p->DstStepX/2);
}
p->Upper = p->DirX > 0;
if (ReUse && NoInc)
{
if (!p->SwapXY && p->DstBPP==16)
I3S(ORR,R0,R0,R0,ROR,16);
if (!p->OnlyDiff)
Inc_RGB_UV_Pixel(p, IncY2, IncUV2);
}
else
{
if (p->DstBPP!=16)
p->Pos = -1;
Stretch_RGB_UV_Pixel(p, Col2, IncY2, IncUV2);
RegDirty = 1;
}
if (!p->SwapXY)
NoInc = !IncY2 && !IncUV2;
else
NoInc = !IncY && !IncUV;
if (p->Pos)
I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
if (p->DstPalette || p->DstBPP==32)
{
if (p->SwapXY)
{
if (RegDirty) { MB(); I2C(LDR,R5,SP,OFS(stack,DstPitch)); }
if (p->DstPalette) Byte();
I3(STR_POST,R0,R9,R5);
}
else
{
if (p->DstPalette) Byte();
I2C(STR_POST,R0,R9,p->DstStepX/2);
}
}
else
{
if (p->SwapXY)
{
if (RegDirty) { MB(); I2C(LDR,R5,SP,OFS(stack,DstPitch)); }
I3(STR_POST,R0,R9,R5);
}
else
I2C(STR_POST,R0,R9,p->DstStepX);
}
if (RegDirty) { MB(); I2C(LDR,R4,SP,OFS(stack,EndOfLine)); }
RegDirty = 0;
if (p->OnlyDiff)
{
MB(); I2C(LDR,R5,SP,OFS(stack,DiffMask));
MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
InstPost(p->Skip);
}
I3(CMP,NONE,R9,R4);
if (Col == ColCount)
{
//last item in block
if (Special)
{
I2C(LDR,R7,SP,OFS(stack,SaveR7));
I2C(LDR,R8,SP,OFS(stack,SaveR8));
I2C(ADD,R7,R7,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
I2C(ADD,R8,R8,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
I2C(STR,R7,SP,OFS(stack,SaveR7));
I2C(STR,R8,SP,OFS(stack,SaveR8));
}
I0P(B,NE,LoopX);
}
else
I0P(B,EQ,EndOfLine);
}
InstPost(EndOfLine);
I2C(LDR,R6,SP,OFS(stack,DstNext));
I2C(LDR,R7,SP,OFS(stack,SrcPitch));
I2C(LDR,R5,SP,OFS(stack,Pos));
I2C(LDR,R12,SP,OFS(stack,Y));
I2C(LDR,R10,SP,OFS(stack,U));
I2C(LDR,R11,SP,OFS(stack,V));
I3(ADD,R9,R9,R6);
//increment row of Y,U,V according to Pos -> Pos+RowStep
RowStep = (p->SwapXY) ? 2:1;
//R4,R6,R8 for temporary
IMul(R6,R5,p->RScaleY); //R6 = RScaleY*Pos
I2C(ADD,R5,R5,RowStep);
IMul(R8,R5,p->RScaleY); //R8 = RScaleY*(Pos+RowStep)
// dY = ((RScaleY * (Pos+RowStep)) >> 4) - ((RScaleY * Pos) >> 4);
I3S(MOV,R4,NONE,R8,LSR,4);
I3S(SUB,R4,R4,R6,LSR,4);
I3(MUL,R4,R7,R4);
// dUV = ((RScaleY * (Pos+RowStep)) >> (4+SrcUVY2)) - ((RScaleY * Pos) >> (4+SrcUVY2));
I3S(MOV,R8,NONE,R8,LSR,4+p->SrcUVY2);
I3S(SUB,R8,R8,R6,LSR,4+p->SrcUVY2);
I3(MUL,R8,R7,R8);
I3(ADD,R12,R12,R4);
I3S(ADD,R10,R10,R8,ASR,p->SrcUVPitch2);
I3S(ADD,R11,R11,R8,ASR,p->SrcUVPitch2);
I2C(STR,R12,SP,OFS(stack,Y));
I2C(STR,R10,SP,OFS(stack,U));
I2C(STR,R11,SP,OFS(stack,V));
//prepare registers for next row
if (p->SwapXY) I2C(LDR,R6,SP,OFS(stack,DstPitch));
I2C(LDR,R4,SP,OFS(stack,Width));
MB(); I2C(LDR,R0,SP,OFS(stack,EndOfRect));
I3(CMP,NONE,R9,R0);
I0P(B,NE,LoopY);
I2C(ADD,SP,SP,OFS(stack,StackFrame));
CodeEnd();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -