2012-03-11 27 views
8

Tôi đã làm việc với RenderScript gần đây với mục đích tạo một API mà một lập trình viên có thể sử dụng một cách dễ dàng, tương tự như cách mà Microsoft Accelerator hoạt động.Cách chuyển các giá trị mảng đến và từ Android RenderScript bằng cách sử dụng Allocations

Sự cố tôi đang gặp phải tại thời điểm này là tôi muốn chuyển giá trị đến và từ lớp RenderScript và mọi thứ chạy theo cách hiệu quả nhất có thể, đây là trích đoạn mã nguồn của tôi cho đến thời điểm này:

int[] A = new int[10]; 
    int[] B = new int[10]; 

    for (int i = 0; i < 10; i++) { 
     A[i] = 2; 
     B[i] = i; 
    } 
    intAdd(A, B); 

Điều này chỉ tạo hai mảng cơ bản và điền chúng với các giá trị và gọi các hàm sẽ gửi chúng tới RenderScript.

private void intAdd(int[] A, int[] B) { 
    RenderScript rs = RenderScript.create(this); 
    ScriptC_rsintadd intaddscript = new ScriptC_rsintadd(rs, getResources(), R.raw.rsintadd); 
    mScript = intaddscript; 

    for(int i = 0; i < A.length; i++) { 
    setNewValues(mScript, A[i], B[i]); 
    intaddscript.invoke_intAdd(); 
    int C = getResult(mScript); 
    notifyUser.append(" " + C); 
    } 
} 

    public void setNewValues(Script script, int A, int B) { 
    mScript.set_numberA(A); 
    mScript.set_numberB(B); 
} 

public int getResult(Script script) { 
    int C = mScript.get_numberC(); 
    return C; 
} 

này sẽ gửi một cặp giá trị vào mã RenderScript sau:

int numberA; 
int numberB; 
int numberC; 

void intAdd() { 
/*Add the two together*/ 
numberC = numberA + numberB; 
/*Send their values to the logcat*/ 
rsDebug("Current Value", numberC); 
} 

Nhưng có hai vấn đề với điều này, một trong những đầu tiên là không đồng bộ bản chất của RenderScript có nghĩa là khi các lớp Java yêu cầu giá trị, kịch bản hoặc chưa thực hiện thao tác, hoặc nó đã thực hiện nó, phá hủy giá trị của đầu ra và bắt đầu trên giá trị tiếp theo. Và nhờ khả năng hiển thị lỗi thấp của RenderScript, không có cách nào để nói.

Vấn đề khác là nó không phải là rất hiệu quả, mã liên tục gọi hàm RenderScript để thêm hai số với nhau. Lý tưởng nhất là tôi muốn vượt qua mảng để RenderScript và lưu trữ nó trong một cấu trúc và có toàn bộ hoạt động được thực hiện trong một cuộc gọi script chứ không phải là nhiều. Nhưng để có được nó trở lại tôi nghĩ rằng tôi sẽ cần phải sử dụng chức năng rsSendtoClient, nhưng tôi đã không tìm thấy bất kỳ tài liệu về cách sử dụng nó. Và tốt hơn là tôi muốn sử dụng chiến lược rsForEach, nhưng một lần nữa thông tin là sợ hãi.

Nếu có bất kỳ ý tưởng nào tôi rất biết ơn. Cảm ơn.

Will Scott-Jackson

Trả lời

2

Tôi không chắc chắn nếu điều này sẽ giúp ích cho bạn vào thời điểm này nhưng kể từ khi tôi biết bao nhiêu của một nỗi đau nó có thể làm việc thông qua RenderScript, đây là sự giúp đỡ tôi có thể cung cấp. Để sử dụng hàm rsSendToClient, bạn cần hướng dẫn cá thể RenderScript mà bạn đã tạo nơi gửi thư đến. Điều này được thực hiện bởi một cái gì đó như:

private void intAdd(int[] A, int[] B) { 
    RenderScript rs = RenderScript.create(this); 

    MySubclassedRSMessageHandler handler = new MySubclassedRSMessageHandler(); 
    rs.setMessageHandler(handler); 
    ScriptC_rsintadd intaddscript = new ScriptC_rsintadd(rs, getResources(), R.raw.rsintadd); 
    mScript = intaddscript; 

    for(int i = 0; i < A.length; i++) { 
      setNewValues(mScript, A[i], B[i]); 
      intaddscript.invoke_intAdd(); 
      int C = getResult(mScript); 
      notifyUser.append(" " + C); 
    } 
} 

Sẽ cần thiết để phân lớp RenderScript.RSMessageHandler và ghi đè phương thức run(). Xem http://developer.android.com/reference/android/renderscript/RenderScript.RSMessageHandler.html nếu bạn chưa có. Về cơ bản không có cách nào để có được xung quanh bản chất không đồng bộ mà tôi tìm thấy là một con dao hai lưỡi. Đối với sự kém hiệu quả, tôi sẽ xem xét việc tạo một cá thể RenderScript, để nó chạy (bạn có thể tạm dừng nó khi không cần thiết, sẽ ở lại trong bộ nhớ nhưng ngăn chặn các chủ đề, do đó không phát sinh chi phí xây dựng mỗi lần bạn gọi một hàm).). Từ đây bạn có thể có cấu trúc của bạn và sau đó sử dụng invoke_myFunction (một số đối số ở đây) từ lớp Java được phản ánh.

Hy vọng điều này sẽ giúp ít nhất một chút.

2

Tôi đã gặp vấn đề tương tự. Vấn đề với chương trình của bạn là không biết khi nào tiện ích chức năng trong tập tin rs nên chạy , hãy thử này nó phải làm việc

public void setNewValues(Script script, int A, int B) { 
mScript.set_numberA(A); 
mScript.set_numberB(B); 
mscript.invoke_intAdd(); 

} 
0

tôi đã cùng một vấn đề với bạn.Tôi nghĩ rằng chức năng rsSendtoClient không hữu ích và tạo ra nhiều lỗi. Thay vào đó, sử dụng một con trỏ và phân bổ nó một bộ nhớ để mang lại kết quả lại cho bạn là dễ dàng hơn nhiều.

Tôi khuyên bạn nên giải pháp của vấn đề của bạn như thế này:

Trong rsintadd.rs sử dụng đoạn mã này:

int32_t *a; 
int32_t *b; 
int32_t *c; 

void intAdd() { 
    for(int i = 0; i<10;i++){ 
    c[i] = a[i] + b[i]; 
} 

Trong sử dụng mã JAVA của bạn đoạn này:

int[] B = new int[10]; 
    int[] A = new int[10]; 

    for (int i = 0; i < 10; i++) { 
     A[i] = 2; 
     B[i] = 1; 
    } 

    // provide memory for b using data in B 
    Allocation b = Allocation.createSized(rs, Element.I32(rs), B.length); 
    b.copyFrom(B); 
    inv.bind_b(b); 

    // provide memory for a using data in A 
    Allocation a = Allocation.createSized(rs, Element.I32(rs), A.length); 
    a.copyFrom(A); 
    inv.bind_a(a); 

    // create blank memory for c 
    inv.bind_c(Allocation.createSized(rs, Element.I32(rs), 10)); 

    // call intAdd function 
    inv.invoke_intAdd(); 

    // get result 
    int[] C = new int[10]; 
    inv.get_c().copyTo(C); 
    for (int i = 0; i < C.length; i++) { 
     System.out.println(C[i]); 
    } 

Và đây là kết quả của bạn trên Logcat:

Result of C

câu hỏi đầu tiên của bạn sắp không đồng bộ, bạn có thể sử dụng thread để chờ đợi kết quả. Trong ví dụ này, hàm này đủ nhanh và ngay lập tức cung cấp đầu ra cho mảng C để kết quả có thể hiển thị trên logcat.

câu hỏi thứ hai của bạn là về thực hiện chức năng intAdd() mà không nhớ lại nó. Đoạn mã trên là câu trả lời. Bạn có thể truy cập bất kỳ phần nào của mảng int trong Java cho đến khi phương thức được thực hiện (khác với hàm root()).

Hy vọng điều này có thể giúp ai đó :)

Các vấn đề liên quan