FSlateShaderResourceProxy* FSlateD3DTextureManager::CreateDynamicTextureResource(FName ResourceName, uint32 Width, uint32 Height, const TArray< uint8 >& RawData)
{
	// Bail out if we already have this texture loaded
	TSharedPtr<FDynamicTextureResource> TextureResource = DynamicTextureMap.FindRef(ResourceName);
	if (TextureResource.IsValid())
	{
		return TextureResource->Proxy;
	}

	// Keep track of non-atlased textures so we can free their resources later
	FSlateD3DTexture* LoadedTexture = new FSlateD3DTexture(Width, Height);

	TextureResource = MakeShareable(new FDynamicTextureResource(LoadedTexture));

	D3D11_SUBRESOURCE_DATA InitData;
	InitData.pSysMem = RawData.GetTypedData();
	InitData.SysMemPitch = Width * 4;

	FNewTextureInfo Info;
	Info.bShouldAtlas = false;
	LoadedTexture->Init(Info.bSrgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM, &InitData);

	TextureResource->Proxy->ActualSize = FIntPoint(Width, Height);
	TextureResource->Proxy->Resource = TextureResource->D3DTexture;

	// Map the new resource for the UTexture so we don't have to load again
	DynamicTextureMap.Add(ResourceName, TextureResource);

	return TextureResource->Proxy;
}
FSlateUpdatableTexture* FSlateD3DRenderer::CreateUpdatableTexture(uint32 Width, uint32 Height)
{
	FSlateD3DTexture* NewTexture = new FSlateD3DTexture(Width, Height);
	NewTexture->Init(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, NULL, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
	return NewTexture;
}
FSlateShaderResourceProxy* FSlateD3DTextureManager::GenerateTextureResource( const FNewTextureInfo& Info )
{
	FSlateShaderResourceProxy* NewProxy = NULL;

	const uint32 Width = Info.TextureData->GetWidth();
	const uint32 Height = Info.TextureData->GetHeight();

	if( Info.bShouldAtlas )
	{
		const uint32 AtlasSize = 1024;
		// 4 bytes per pixel
		const uint32 AtlasStride = sizeof(uint8)*4; 
		const uint8 Padding = 1;
		const FAtlasedTextureSlot* NewSlot = NULL;

		FSlateTextureAtlasD3D* Atlas = NULL;

		// Get the last atlas and find a slot for the texture
		for( int32 AtlasIndex = 0; AtlasIndex < TextureAtlases.Num(); ++AtlasIndex )
		{
			Atlas = TextureAtlases[AtlasIndex];
			NewSlot = Atlas->AddTexture( Width, Height, Info.TextureData->GetRawBytes() );
			if( NewSlot )
			{
				break;
			}
		}

		// No new slot was found in any atlas so we have to make another one
		if( !NewSlot )
		{
			// A new slot in the atlas could not be found, make a new atlas and add the texture to it
			Atlas = new FSlateTextureAtlasD3D( AtlasSize, AtlasSize, AtlasStride, Padding );
			TextureAtlases.Add( Atlas );
			NewSlot = TextureAtlases.Last()->AddTexture( Width, Height, Info.TextureData->GetRawBytes() );
		}

		check( Atlas && NewSlot );

		// Create a proxy representing this texture in the atlas
		NewProxy = new FSlateShaderResourceProxy;
		NewProxy->Resource = Atlas->GetAtlasTexture();
		// Compute the sub-uvs for the location of this texture in the atlas, accounting for padding
		NewProxy->StartUV = FVector2D( (float)(NewSlot->X+Padding) / Atlas->GetWidth(), (float)(NewSlot->Y+Padding) / Atlas->GetHeight() );
		NewProxy->SizeUV = FVector2D( (float)(NewSlot->Width-Padding*2) / Atlas->GetWidth(), (float)(NewSlot->Height-Padding*2) / Atlas->GetHeight() );
		NewProxy->ActualSize = FIntPoint( Width, Height );
	}
	else
	{
		// The texture is not atlased create a new texture proxy and just point it to the actual texture
		NewProxy = new FSlateShaderResourceProxy;

		// Keep track of non-atlased textures so we can free their resources later
		FSlateD3DTexture* Texture = new FSlateD3DTexture( Width, Height );
		NonAtlasedTextures.Add( Texture );

		NewProxy->Resource = Texture;
		NewProxy->StartUV = FVector2D(0.0f,0.0f);
		NewProxy->SizeUV = FVector2D(1.0f, 1.0f);
		NewProxy->ActualSize = FIntPoint( Width, Height );

		D3D11_SUBRESOURCE_DATA InitData;
		InitData.pSysMem = Info.TextureData->GetRawBytes().GetTypedData();
		InitData.SysMemPitch = Width * 4;

		Texture->Init( Info.bSrgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM, &InitData );
	}

	return NewProxy;
}