Reputation: 4482
I want to process a bitmap in my Android application - the bitmap can be huge, so I use multithreading to perform faster operations. Here's my code (part of Runnable child):
@Override
public void run() {
int imageHeight = filter.getBitmap().getHeight();
int start = threadNumber * imageHeight / threadCount;
int stop = (threadNumber + 1) * imageHeight / threadCount;
for (int j = start; j < stop; j++) {
filter.processLine(j);
}
}
//...
protected void processLine(int lineNumber)
{
int width = bitmap.getWidth();
int pixels[] = new int[width];
bitmap.getPixels(pixels, 0, width, 0, lineNumber, width, 1);
for (int i = 0; i < width; i++) {
pixels[i] = processPixel(pixels[i]);
}
bitmap.setPixels(pixels, 0, width, 0, lineNumber, width, 1);
}
When I use only 1 thread in the pool, everything works properely. Unfortunetely, when I use thread number equal to number of cores of the processor (4 in my device) the result is like following (for grayscale filter):
It looks like sometimes:
Am I right? Are these functions thread-unsafe? How should I perform multi-thread bitmap filtering to be fast and thread-safe?
Upvotes: 3
Views: 1307
Reputation: 30985
2D image processing in Android is provided by the Skia library, also used by Chrome.
It's hard to find a definitive answer. "Skia is not thread-safe, although SkBitmap [used by Bitmap] is thread-safe..." I don't know what to think. I perused a bunch of inscrutable JNI/C++ code and this is the best I can offer (which seems to be more than anyone else can do):
I think you should call bitmap.getPixels()
on the entire bitmap. Then divide up the resulting array and thread out the processing. When all the threads are completed, re-assemble the results and call bitmap.setPixels()
It seems like bitmap.getPixels()
and bitmap.setPixels()
should be nothing more than memcpy()
s, but there is a lot more going on under the hood with reference counts, image caches, color space conversions, premultiplications and who knows what else. Taking the Bitmap
methods out of concurrent processing should keep you out of trouble.
Upvotes: 4