bool BumpChunk::canAlloc(size_t n) { char *aligned = AlignPtr(bump); char *bumped = aligned + n; return bumped <= limit && bumped > headerBase(); }
/// Allocate - Allocate space at the specified alignment. /// void *BumpPtrAllocator::Allocate(size_t Size, size_t Alignment) { if (!CurSlab) // Start a new slab if we haven't allocated one already. StartNewSlab(); // Keep track of how many bytes we've allocated. BytesAllocated += Size; // 0-byte alignment means 1-byte alignment. if (Alignment == 0) Alignment = 1; // Allocate the aligned space, going forwards from CurPtr. char *Ptr = AlignPtr(CurPtr, Alignment); // Check if we can hold it. if (Ptr + Size <= End) { CurPtr = Ptr + Size; return Ptr; } // If Size is really big, allocate a separate slab for it. size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1; if (PaddedSize > SizeThreshold) { MemSlab *NewSlab = Allocator.Allocate(PaddedSize); // Put the new slab after the current slab, since we are not allocating // into it. NewSlab->NextPtr = CurSlab->NextPtr; CurSlab->NextPtr = NewSlab; Ptr = AlignPtr((char*)(NewSlab + 1), Alignment); assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size); return Ptr; } // Otherwise, start a new slab and try again. StartNewSlab(); Ptr = AlignPtr(CurPtr, Alignment); CurPtr = Ptr + Size; assert(CurPtr <= End && "Unable to allocate memory!"); return Ptr; }
BumpChunk * BumpChunk::new_(size_t chunkSize) { JS_ASSERT(RoundUpPow2(chunkSize) == chunkSize); void *mem = js_malloc(chunkSize); if (!mem) return NULL; BumpChunk *result = new (mem) BumpChunk(chunkSize - sizeof(BumpChunk)); /* * We assume that the alignment of sAlign is less than that of * the underlying memory allocator -- creating a new BumpChunk should * always satisfy the sAlign alignment constraint. */ JS_ASSERT(AlignPtr(result->bump) == result->bump); return result; }
Sprite *Blitter_32bppOptimized::Encode(SpriteLoader::Sprite *sprite, AllocatorProc *allocator) { /* streams of pixels (a, r, g, b channels) * * stored in separated stream so data are always aligned on 4B boundary */ Colour *dst_px_orig[ZOOM_LVL_COUNT]; /* interleaved stream of 'm' channel and 'n' channel * 'n' is number if following pixels with the same alpha channel class * there are 3 classes: 0, 255, others * * it has to be stored in one stream so fewer registers are used - * x86 has problems with register allocation even with this solution */ uint8 *dst_n_orig[ZOOM_LVL_COUNT]; /* lengths of streams */ uint32 lengths[ZOOM_LVL_COUNT][2]; for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) { const SpriteLoader::Sprite *src_orig = ResizeSprite(sprite, z); uint size = src_orig->height * src_orig->width; dst_px_orig[z] = CallocT<Colour>(size + src_orig->height * 2); dst_n_orig[z] = CallocT<uint8>(size * 2 + src_orig->height * 4 * 2); uint32 *dst_px_ln = (uint32 *)dst_px_orig[z]; uint32 *dst_n_ln = (uint32 *)dst_n_orig[z]; const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *)src_orig->data; for (uint y = src_orig->height; y > 0; y--) { Colour *dst_px = (Colour *)(dst_px_ln + 1); uint8 *dst_n = (uint8 *)(dst_n_ln + 1); uint8 *dst_len = dst_n++; uint last = 3; int len = 0; for (uint x = src_orig->width; x > 0; x--) { uint8 a = src->a; uint t = a > 0 && a < 255 ? 1 : a; if (last != t || len == 255) { if (last != 3) { *dst_len = len; dst_len = dst_n++; } len = 0; } last = t; len++; if (a != 0) { dst_px->a = a; *dst_n = src->m; if (src->m != 0) { /* Pre-convert the mapping channel to a RGB value */ uint32 colour = this->LookupColourInPalette(src->m); dst_px->r = GB(colour, 16, 8); dst_px->g = GB(colour, 8, 8); dst_px->b = GB(colour, 0, 8); } else { dst_px->r = src->r; dst_px->g = src->g; dst_px->b = src->b; } dst_px++; dst_n++; } else if (len == 1) { dst_px++; *dst_n = src->m; dst_n++; } src++; } if (last != 3) { *dst_len = len; } dst_px = (Colour *)AlignPtr(dst_px, 4); dst_n = (uint8 *)AlignPtr(dst_n, 4); *dst_px_ln = (uint8 *)dst_px - (uint8 *)dst_px_ln; *dst_n_ln = (uint8 *)dst_n - (uint8 *)dst_n_ln; dst_px_ln = (uint32 *)dst_px; dst_n_ln = (uint32 *)dst_n; } lengths[z][0] = (byte *)dst_px_ln - (byte *)dst_px_orig[z]; // all are aligned to 4B boundary lengths[z][1] = (byte *)dst_n_ln - (byte *)dst_n_orig[z]; free(src_orig->data); free((void *)src_orig); } uint len = 0; // total length of data for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) { len += lengths[z][0] + lengths[z][1]; } Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(SpriteData) + len); dest_sprite->height = sprite->height; dest_sprite->width = sprite->width; dest_sprite->x_offs = sprite->x_offs; dest_sprite->y_offs = sprite->y_offs; SpriteData *dst = (SpriteData *)dest_sprite->data; for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) { dst->offset[z][0] = z == ZOOM_LVL_BEGIN ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1]; dst->offset[z][1] = lengths[z][0] + dst->offset[z][0]; memcpy(dst->data + dst->offset[z][0], dst_px_orig[z], lengths[z][0]); memcpy(dst->data + dst->offset[z][1], dst_n_orig[z], lengths[z][1]); free(dst_px_orig[z]); free(dst_n_orig[z]); } return dest_sprite; }
Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) { /* streams of pixels (a, r, g, b channels) * * stored in separated stream so data are always aligned on 4B boundary */ Colour *dst_px_orig[ZOOM_LVL_COUNT]; /* interleaved stream of 'm' channel and 'n' channel * 'n' is number of following pixels with the same alpha channel class * there are 3 classes: 0, 255, others * * it has to be stored in one stream so fewer registers are used - * x86 has problems with register allocation even with this solution */ uint16 *dst_n_orig[ZOOM_LVL_COUNT]; /* lengths of streams */ uint32 lengths[ZOOM_LVL_COUNT][2]; ZoomLevel zoom_min; ZoomLevel zoom_max; if (sprite->type == ST_FONT) { zoom_min = ZOOM_LVL_NORMAL; zoom_max = ZOOM_LVL_NORMAL; } else { zoom_min = _settings_client.gui.zoom_min; zoom_max = _settings_client.gui.zoom_max; if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX; } for (ZoomLevel z = zoom_min; z <= zoom_max; z++) { const SpriteLoader::Sprite *src_orig = &sprite[z]; uint size = src_orig->height * src_orig->width; dst_px_orig[z] = CallocT<Colour>(size + src_orig->height * 2); dst_n_orig[z] = CallocT<uint16>(size * 2 + src_orig->height * 4 * 2); uint32 *dst_px_ln = (uint32 *)dst_px_orig[z]; uint32 *dst_n_ln = (uint32 *)dst_n_orig[z]; const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *)src_orig->data; for (uint y = src_orig->height; y > 0; y--) { Colour *dst_px = (Colour *)(dst_px_ln + 1); uint16 *dst_n = (uint16 *)(dst_n_ln + 1); uint16 *dst_len = dst_n++; uint last = 3; int len = 0; for (uint x = src_orig->width; x > 0; x--) { uint8 a = src->a; uint t = a > 0 && a < 255 ? 1 : a; if (last != t || len == 65535) { if (last != 3) { *dst_len = len; dst_len = dst_n++; } len = 0; } last = t; len++; if (a != 0) { dst_px->a = a; *dst_n = src->m; if (src->m != 0) { /* Get brightest value */ uint8 rgb_max = max(src->r, max(src->g, src->b)); /* Black pixel (8bpp or old 32bpp image), so use default value */ if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS; *dst_n |= rgb_max << 8; /* Pre-convert the mapping channel to a RGB value */ Colour colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), rgb_max); dst_px->r = colour.r; dst_px->g = colour.g; dst_px->b = colour.b; } else { dst_px->r = src->r; dst_px->g = src->g; dst_px->b = src->b; } dst_px++; dst_n++; } else if (len == 1) { dst_px++; *dst_n = src->m; dst_n++; } src++; } if (last != 3) { *dst_len = len; } dst_px = (Colour *)AlignPtr(dst_px, 4); dst_n = (uint16 *)AlignPtr(dst_n, 4); *dst_px_ln = (uint8 *)dst_px - (uint8 *)dst_px_ln; *dst_n_ln = (uint8 *)dst_n - (uint8 *)dst_n_ln; dst_px_ln = (uint32 *)dst_px; dst_n_ln = (uint32 *)dst_n; } lengths[z][0] = (byte *)dst_px_ln - (byte *)dst_px_orig[z]; // all are aligned to 4B boundary lengths[z][1] = (byte *)dst_n_ln - (byte *)dst_n_orig[z]; } uint len = 0; // total length of data for (ZoomLevel z = zoom_min; z <= zoom_max; z++) { len += lengths[z][0] + lengths[z][1]; } Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(SpriteData) + len); dest_sprite->height = sprite->height; dest_sprite->width = sprite->width; dest_sprite->x_offs = sprite->x_offs; dest_sprite->y_offs = sprite->y_offs; SpriteData *dst = (SpriteData *)dest_sprite->data; memset(dst, 0, sizeof(*dst)); for (ZoomLevel z = zoom_min; z <= zoom_max; z++) { dst->offset[z][0] = z == zoom_min ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1]; dst->offset[z][1] = lengths[z][0] + dst->offset[z][0]; memcpy(dst->data + dst->offset[z][0], dst_px_orig[z], lengths[z][0]); memcpy(dst->data + dst->offset[z][1], dst_n_orig[z], lengths[z][1]); free(dst_px_orig[z]); free(dst_n_orig[z]); } return dest_sprite; }
void EDFAlloc(const Scene* scene, uint offset, const LightPoint* lpos, uchar* EDF) { if (lpos->atInfinity) { EnvEDFHead* envEDFHead = (EnvEDFHead*)EDF; envEDFHead->ddfHead._type = DDFType_EnvEDF; const uchar* lightsData_p = scene->materialsData + scene->environment->idx_envLightProperty; const LightPropertyInfo* lpInfo = (const LightPropertyInfo*)lightsData_p; envEDFHead->numEnvEEDFs = lpInfo->numEEDFs; envEDFHead->offsetsEnvEEDFs[0] = envEDFHead->offsetsEnvEEDFs[1] = envEDFHead->offsetsEnvEEDFs[2] = envEDFHead->offsetsEnvEEDFs[3] = 0; uchar* EDFp = EDF + sizeof(EnvEDFHead); lightsData_p += sizeof(LightPropertyInfo); for (int i = 0; i < envEDFHead->numEnvEEDFs; ++i) { AlignPtrG(&lightsData_p, 4); uchar EnvLPElemID = *lightsData_p; switch (EnvLPElemID) { case EnvLPElem_ImageBased: { AlignPtr(&EDFp, 16); envEDFHead->offsetsEnvEEDFs[i] = (ushort)((uintptr_t)EDFp - (uintptr_t)EDF); EntireSceneEmission* entire = (EntireSceneEmission*)EDFp; const ImageBasedEnvLElem* llIBEnvElem = (const ImageBasedEnvLElem*)lightsData_p; entire->head.id = EnvEEDFID_EntireSceneEmission; entire->head.eLeType = EEDF_Diffuse; entire->Le = evaluateColorTexture(scene->texturesData + llIBEnvElem->idx_Le, lpos->uv) * llIBEnvElem->multiplier; EDFp += sizeof(EntireSceneEmission); lightsData_p += sizeof(ImageBasedEnvLElem); break; } default: { break; } } } } else { EDFHead* LeHead = (EDFHead*)EDF; LeHead->ddfHead._type = DDFType_EDF; const uchar* lightsData_p = scene->materialsData + offset; const LightPropertyInfo* lpInfo = (const LightPropertyInfo*)lightsData_p; LeHead->numEEDFs = lpInfo->numEEDFs; LeHead->offsetsEEDFs[0] = LeHead->offsetsEEDFs[1] = LeHead->offsetsEEDFs[2] = LeHead->offsetsEEDFs[3] = 0; LeHead->n = lpos->sNormal; if (lpos->hasTangent) LeHead->s = lpos->sTangent; else makeTangent(&lpos->sNormal, &LeHead->s); LeHead->t = cross(LeHead->n, LeHead->s); LeHead->ng = lpos->gNormal; uchar* EDFp = EDF + sizeof(EDFHead); lightsData_p += sizeof(LightPropertyInfo); for (int i = 0; i < LeHead->numEEDFs; ++i) { AlignPtrG(&lightsData_p, 4); uchar EEDFID = *lightsData_p; switch (EEDFID) { case EEDFID_DiffuseEmission: { AlignPtr(&EDFp, 16); LeHead->offsetsEEDFs[i] = (ushort)((uintptr_t)EDFp - (uintptr_t)EDF); DiffuseEmission* diffuse = (DiffuseEmission*)EDFp; DiffuseLElem* diffuseElem = (DiffuseLElem*)lightsData_p; diffuse->head.id = EEDFID_DiffuseEmission; diffuse->head.eLeType = EEDF_Diffuse; diffuse->M = evaluateColorTexture(scene->texturesData + diffuseElem->idx_M, lpos->uv); EDFp += sizeof(DiffuseEmission); lightsData_p += sizeof(DiffuseLElem); break; } default: { break; } } } } }