Передача массива в rsForEach в Renderscript Compute

Я обнаружил, что в RenderScript отсутствует хорошая документация, поскольку я знаю, что forEach в RS должен выполнять root () для каждого отдельного элемента в распределении.

Я пытаюсь создать библиотеку для Renderscript, которая обрабатывает изображения, в качестве отправной точки, я достиг этого замечательного ответа . Но проблема заключается в том, что операция размытия находится на каждом пикселе, и каждый пиксель требует другого цикла (n с шириной размытия) вычисления. Хотя он работает на многоядерном процессоре, он все еще слишком медленный.

Я пытаюсь изменить его, чтобы разрешить (двухпроходный) фильтр окна, но для этого требуется работа над одной строкой или столбцом вместо ячейки. Итак, есть ли способ просить foreach отправить массив в root ()?

Solutions Collecting From Web of "Передача массива в rsForEach в Renderscript Compute"

RsForEach может работать только на Allocations.

Если вы хотите, чтобы функция rsForEach вызывала root () для каждой строки изображения, которую вы должны передать в распределении, размер которой равен той же длине, что и количество строк, а затем выработать, какую строку вы должны использовать внутри Root () (аналогично для работы в каждом столбце). Затем RenderScript должен разделить работу для работы на доступных ресурсах (более одной строки обрабатываются одновременно на многоядерных устройствах).

Один из способов сделать это – передать в Allocation, которые дают смещения (в массиве данных изображения) строк изображения. Аргумент v_in внутри корня () будет тогда смещением строки. Поскольку Allocations, на который работает вызов rsForEach, не являются данными изображения, вы не можете записать изображение с помощью аргумента v_out, и вы должны привязать выходное изображение отдельно.

Вот некоторые RenderScript, которые показывают это:

 #pragma version(1) #pragma rs java_package_name(com.android.example.hellocompute) rs_allocation gIn; rs_allocation gOut; rs_script gScript; int mImageWidth; const uchar4 *gInPixels; uchar4 *gOutPixels; void init() { } static const int kBlurWidth = 20; // // This is called per row. // The row indices are passed in as v_in or you could also use the x argument and multiply it by image width. // void root(const int32_t *v_in, int32_t *v_out, const void *usrData, uint32_t x, uint32_t y) { float3 blur[kBlurWidth]; float3 cur_colour = {0.0f, 0.0f, 0.0f}; for ( int i = 0; i < kBlurWidth; i++) { float3 init_colour = {0.0f, 0.0f, 0.0f}; blur[i] = init_colour; } int32_t row_index = *v_in; int blur_index = 0; for ( int i = 0; i < mImageWidth; i++) { float4 pixel_colour = rsUnpackColor8888(gInPixels[i + row_index]); cur_colour -= blur[blur_index]; blur[blur_index] = pixel_colour.rgb; cur_colour += blur[blur_index]; blur_index += 1; if ( blur_index >= kBlurWidth) { blur_index = 0; } gOutPixels[i + row_index] = rsPackColorTo8888(cur_colour/(float)kBlurWidth); //gOutPixels[i + row_index] = rsPackColorTo8888(pixel_colour); } } void filter() { rsDebug("Number of rows:", rsAllocationGetDimX(gIn)); rsForEach(gScript, gIn, gOut, NULL); } 

Это будет настройка с использованием следующей Java:

  mBlurRowScript = new ScriptC_blur_row(mRS, getResources(), R.raw.blur_row); int row_width = mBitmapIn.getWidth(); // // Create an allocation that indexes each row. // int num_rows = mBitmapIn.getHeight(); int[] row_indices = new int[num_rows]; for ( int i = 0; i < num_rows; i++) { row_indices[i] = i * row_width; } Allocation row_indices_alloc = Allocation.createSized( mRS, Element.I32(mRS), num_rows, Allocation.USAGE_SCRIPT); row_indices_alloc.copyFrom(row_indices); // // The image data has to be bound to the pointers within the RenderScript so it can be accessed // from the root() function. // mBlurRowScript.bind_gInPixels(mInAllocation); mBlurRowScript.bind_gOutPixels(mOutAllocation); // Pass in the image width mBlurRowScript.set_mImageWidth(row_width); // // Pass in the row indices Allocation as the input. It is also passed in as the output though the output is not used. // mBlurRowScript.set_gIn(row_indices_alloc); mBlurRowScript.set_gOut(row_indices_alloc); mBlurRowScript.set_gScript(mBlurRowScript); mBlurRowScript.invoke_filter();