2014-03-25 118 views
4

我想知道在android應用程序運行時是否可以編寫/修改renderscript代碼。 我的主要目標是製作一個應用程序,用戶可以在沒有任何Java知識的情況下學習如何使用renderscript。該應用程序的基本佈局將包含一個輸入和輸出圖像,並可以輸入代碼。這個應用程序的基本功能已經在工作,這是一個界面的圖像。 App layout在運行時編譯renderscript代碼

從應用程序直接反饋測試renderscript代碼將是有用的。

我已經做過研究關於構建過程,並與下面的想法來到了起來:

一個基本的「模板」的renderScript文件,與像進出分配必要的全局變量。

我的java代碼會創建一個生成的java類的腳本對象,並對這些全局腳本變量進行基本的初始化。 該模板.rs文件的根函數將爲空,並且應該可以在運行時由用戶實現。

當用戶在應用程序的主視圖中鍵入他的代碼時,代碼將寫入我自己的.rs文件,然後由應用程序調用由llvm-rs-cc編譯器編譯。生成的.bc將被複制到模板的原始.bc文件 的位置。由於代碼的唯一更改發生在根函數內部,所以不需要對周圍的代碼進行更改。

我現在遇到的問題是,.bc文件捆綁在res/raw文件夾中的最終apk內, 這是應用程序無法訪問的。因此用新生成的文件覆蓋舊的.bc文件是不可能的。

在運行時是否有(另一種)方式來編譯renderscript代碼?

編輯:解決方法可以在這github鏈接找到。欲瞭解更多詳情,請this回答,請閱讀最後評論

回答

2

你將不得不改變產生的膠類(ScriptC_mono),它至少是鹼(ScriptC)。

<ExtremeHax>

.bc文件被讀取並流傳下來到renderScript的內部。據我所知,這是在ScriptC.internalCreate()之內完成的,該鏈接用於讀取原始資源。您需要它來從您控制的位置讀取文件。可能你只需要修改internalCreate(),但可能會有複雜性需要更廣泛的編輯。

一旦實施RuntimeScriptC,您應該修改ScriptC_mono以繼承該基類而不是ScriptC

正如您所指出的那樣,您可以對rs代碼進行的更改非常有限,因爲您無法在運行時修改膠水類。例如,你不能改變內核的簽名。但是,您可以進一步深入研究:如果您放棄膠水類,可以進行任何您想要的更改。

內核是通過索引而不是按名稱在glue類中調用的,而type/element檢查是在glue類中完成的。因此,即使你改變了內核的簽名,只要你知道它的索引以及內外分配的類型,你仍然可以直接使用forEach()來調用它。

public class ScriptC_mono extends ScriptC { 
    //... 

    public void forEach_root(Allocation ain, Allocation aout) { 
    // check ain 
    if (!ain.getType().getElement().isCompatible(__U8_4)) { 
     throw new RSRuntimeException("Type mismatch with U8_4!"); 
    } 
    // check aout 
    if (!aout.getType().getElement().isCompatible(__U8_4)) { 
     throw new RSRuntimeException("Type mismatch with U8_4!"); 
      // Verify dimensions 
    Type tIn = ain.getType(); 
    Type tOut = aout.getType(); 
    if ((tIn.getCount() != tOut.getCount()) || 
     (tIn.getX() != tOut.getX()) || 
     (tIn.getY() != tOut.getY()) || 
     (tIn.getZ() != tOut.getZ()) || 
     (tIn.hasFaces() != tOut.hasFaces()) || 
     (tIn.hasMipmaps() != tOut.hasMipmaps())) { 
     throw new RSRuntimeException("Dimension mismatch between input and output parameters!"); 
    } 
    forEach(mExportForEachIdx_root, ain, aout, null); 
    } 
} 

</ExtremeHax>

+0

感謝您對這個漂亮的答案,我會嘗試這第一件事明天! – DeGoosseZ

+0

祝你好運。好奇心:你打算如何在設備上調用'llvm-rs-cc'? – Kietz

+0

仍然需要嘗試一些東西,但我已經閱讀了有關虛擬linux機器,並且能夠從命令行調用它們。所以用java exec我可以嘗試啓動它。但正如我所說,仍然有很多事情我需要找出,並希望我可以設法把它們合在一起.. – DeGoosseZ