Is it possible to write pixels to a texture through a native (unmanaged) plugin without blocking Unity while you’re doing it?
I’ve been trying to figure out how to quickly update textures by passing a NativeTexturePtr to a plugin ( Slowness updating textures through dll? - Unity Answers ), but I’m finding that doing so causes Unity rendering to hang while the texture is being updated. I’m trying to understand why this is happening, and if there’s a better way to be doing it.
My guess is that the plugin execution is happening on the main Unity thread, and for whatever reason assigning & pushing the texture to the GPU is taking a long time and causing Unity itself to pause for up to 30 ms each frame.
Is there a way to make this process asynchronous, if Unity isn’t currently using the texture in question for rendering? Is there a way to build a second texture on a different thread and simply copy it over when finished (a way that works in both DirectX and OpenGL)? Or some other trick to do it asynchronously so Unity doesn’t end up hanging?
My current plugin code, based on the Unity plugin example (this is only the part for DX9):
IDirect3DTexture9* d3dtex = (IDirect3DTexture9*)g_TexturePointer;
D3DSURFACE_DESC desc;
d3dtex->GetLevelDesc (0, &desc);
D3DLOCKED_RECT lr;
d3dtex->LockRect (0, &lr, NULL, 0);
FillTextureFromCode (desc.Width, desc.Height, lr.Pitch, (unsigned char*)lr.pBits);
d3dtex->UnlockRect (0);
FillTextureFromCode just loops through the texture, using the pointer to update the texture memory:
const float t = g_Time * 4.0f;
int randNum = rand() % 256;
for (int y = 0; y < height; ++y)
{
unsigned char* ptr = dst;
for (int x = 0; x < width; ++x)
{
int vv = randNum; //rand() % 256; //randNum; //int(t);
// Write the texture pixel
ptr[0] = vv;
ptr[1] = vv;
ptr[2] = vv;
ptr[3] = vv;
// To next pixel (our pixels are 4 bpp)
ptr += 4;
}
// To next image row
dst += stride;
}