// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ BlastCopy16 // ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // BlastCopy16 is used in the same way as BlastCopy except it does 16 bit deep copies void BlastCopy16(BCPtr source,BCPtr dest,const Rect *sourceRect,const Rect *destRect) { unsigned char *srcPtr,*destPtr,*srcRowStart,*destRowStart; unsigned long miscCount; unsigned long yCount; unsigned long heightToCopy=sourceRect->bottom-sourceRect->top; unsigned long widthToCopy=sourceRect->right-sourceRect->left; unsigned long srcRB,destRB; srcRB=source->rowBytes; destRB=dest->rowBytes; srcRowStart=source->baseAddr+srcRB*sourceRect->top+sourceRect->left*sizeof(unsigned short); destRowStart=dest->baseAddr+destRB*destRect->top+destRect->left*sizeof(unsigned short); if (IsDoubleAligned(srcRowStart,destRowStart,srcRB,destRB)) { BlastCopyDoubleAligned(srcRowStart,destRowStart,srcRB,destRB,widthToCopy*2,heightToCopy); return; } for (yCount=0; yCount<heightToCopy; yCount++) { srcPtr=srcRowStart; srcRowStart+=srcRB; destPtr=destRowStart; destRowStart+=destRB; miscCount=widthToCopy; // Move the data in the biggest chunks possible #ifdef powerc // raa PowerPC 601, 8 bytes in one move command if (g601Chip) { while (miscCount>=sizeof(double)/2) { *((double *)destPtr)++=*((double *)srcPtr)++; miscCount-=sizeof(double)/2; } } #endif while(miscCount>=sizeof(unsigned long)/2) { *((unsigned long *)destPtr)++=*((unsigned long *)srcPtr)++; miscCount-=sizeof(unsigned long)/2; } while(miscCount>=sizeof(unsigned short)/2) { *((unsigned short *)destPtr)++=*((unsigned short *)srcPtr)++; miscCount-=sizeof(unsigned short)/2; } } }
// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ BlastCopy16 // ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // BlastCopy16 is used in the same way as BlastCopy except it does 16 bit deep copies void BlastCopy16(BCPtr source,BCPtr dest,const Rect *sourceRect,const Rect *destRect) { unsigned char *srcPtr,*destPtr,*srcRowStart,*destRowStart; unsigned long miscCount; unsigned long yCount; unsigned long heightToCopy=sourceRect->bottom-sourceRect->top; unsigned long widthToCopy=sourceRect->right-sourceRect->left; unsigned long srcRB,destRB; srcRB=source->rowBytes; destRB=dest->rowBytes; srcRowStart=source->baseAddr+srcRB*sourceRect->top+sourceRect->left*sizeof(unsigned short); destRowStart=dest->baseAddr+destRB*destRect->top+destRect->left*sizeof(unsigned short); if (IsDoubleAligned(srcRowStart,destRowStart,srcRB,destRB)) { BlastCopyDoubleAligned(srcRowStart,destRowStart,srcRB,destRB,widthToCopy*2,heightToCopy); return; } for (yCount=0; yCount<heightToCopy; yCount++) { srcPtr=srcRowStart; srcRowStart+=srcRB; destPtr=destRowStart; destRowStart+=destRB; miscCount=widthToCopy; // Move the data in the biggest chunks possible while (miscCount>=sizeof(double)/2) { unsigned long long *aDestPtr = ((unsigned long long *)destPtr); unsigned long long *aSrcPtr = ((unsigned long long *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount-=sizeof(unsigned long long)/2; } while(miscCount>=sizeof(unsigned long)/2) { unsigned long *aDestPtr = ((unsigned long *)destPtr); unsigned long *aSrcPtr = ((unsigned long *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount -= sizeof(unsigned long)/2; } while(miscCount>=sizeof(unsigned short)/2) { unsigned short *aDestPtr = ((unsigned short *)destPtr); unsigned short *aSrcPtr = ((unsigned short *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount -= sizeof(unsigned short)/2; } } }
// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ BlastCopyDoubleAligned // ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // Blits sections of copy that are 8 byte aligned using doubles, blits stragglers either ends using longs/shorts/bytes void BlastCopyDoubleAligned( unsigned char *inSource, unsigned char *inDest, unsigned long inSourceRB, unsigned long inDestRB, unsigned long inLength, // inLength in bytes unsigned long inRows) { unsigned char *srcPtr=inSource,*destPtr=inDest; unsigned long leftSectionLength,midSectionLength,rightSectionLength,miscCount; // all in bytes unsigned char *destRowEnd=inDest+inLength; // Verify BlastAssert_(IsDoubleAligned(inSource,inDest,inSourceRB,inDestRB)); // copy is split into 3 for each row // copy until 8 byte aligned // copy 8 byte aligned data // copy until end of row // Examples: // 012345670123456701234567012345670 // |*******|*******|*******|*******| // ++++++++ left=3, mid=0, right=5 // +++ left=3, mid=0, right=0 // +++++++++++++++ left=5, mid=8, right=2 // ++++ left=2, mid=0, right=2 if (inLength>=8) { // work out length of left side if ((UInt32)srcPtr&7) leftSectionLength=8-(UInt32)srcPtr&7; else leftSectionLength=0; // work out length of right section rightSectionLength=(UInt32)destRowEnd&7; // if both left and right are in the same 8 byte block then we do all copying in the left side if ((leftSectionLength+rightSectionLength)>inLength) { midSectionLength=0; rightSectionLength=0; } else midSectionLength=inLength-(leftSectionLength+rightSectionLength); } else { leftSectionLength=inLength; midSectionLength=0; rightSectionLength=0; } // double check our maths if in debug mode BlastAssert_(inLength==leftSectionLength+rightSectionLength+midSectionLength); // check total data length BlastAssert_((midSectionLength&7)==0); // multiple of 8 #if BLAST_DEBUG // make sure we've not hosed our mid section 8 byte aligned stuff unsigned char *midSource=srcPtr+leftSectionLength,*midDest=destPtr+leftSectionLength; if (midSectionLength) { BlastAssert_(((UInt32)midSource&7)==0); BlastAssert_(((UInt32)midDest&7)==0); } #endif // copy across rows and then down inRows++; while (--inRows) { // copy left side if (leftSectionLength) { miscCount=leftSectionLength; while(miscCount>=sizeof(unsigned long)) { unsigned long *aDestPtr = ((unsigned long *)destPtr); unsigned long *aSrcPtr = ((unsigned long *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount-=sizeof(unsigned long); } while(miscCount>=sizeof(unsigned short)) { unsigned short *aDestPtr = ((unsigned short *)destPtr); unsigned short *aSrcPtr = ((unsigned short *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount-=sizeof(unsigned short); } if (miscCount == 1) *destPtr++=*srcPtr++; } // copy mid section using doubles miscCount=midSectionLength; while (miscCount>=sizeof(unsigned long long)) { unsigned long long *aDestPtr = ((unsigned long long *)destPtr); unsigned long long *aSrcPtr = ((unsigned long long *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount-=sizeof(unsigned long long); } // copy right side if (rightSectionLength) { miscCount=rightSectionLength; while(miscCount>=sizeof(unsigned long)) { unsigned long *aDestPtr = ((unsigned long *)destPtr); unsigned long *aSrcPtr = ((unsigned long *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount-=sizeof(unsigned long); } while(miscCount>=sizeof(unsigned short)) { unsigned short *aDestPtr = ((unsigned short *)destPtr); unsigned short *aSrcPtr = ((unsigned short *)srcPtr); *aDestPtr = *aSrcPtr; aDestPtr++; aSrcPtr++; miscCount -= sizeof(unsigned short); } if (miscCount == 1) *destPtr++ = *srcPtr++; } // next row inSource+=inSourceRB; srcPtr=inSource; inDest+=inDestRB; destPtr=inDest; } }