Example #1
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
 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;
                 }
             }
         }
     }
 }