以äžãAndroidéçºããŒã ã®ãšã³ãžãã¢ã§ããR. Jason Samsã代衚ããŠã
Renderscriptã®çŽ¹ä»ã§ããã®ãã¯ãããžãŒã®æŠèŠã説æããŸããã ãã®æçš¿ã§ã¯ããã³ã³ãã¥ãŒãã£ã³ã°ãã«éäžããŸãã Renderscriptã®çšèªã§ã¯ããèšç®ããšã¯ãããŒã¿åŠçã®Dalvikã³ãŒãããRenderscriptã³ãŒããžã®ç¹å®ã®ãªãããŒããæå³ããåãããã»ããµãŸãã¯ä»ã®ããã»ããµïŒè€æ°ïŒã§å®è¡ã§ããŸãã
Renderscriptãã¶ã€ã³ã®ç®æš
Renderscriptã«ã¯3ã€ã®äž»èŠãªç®æšããããéèŠåºŠã®é«ããã®ããäœããã®ã®é ã«ããããæ€èšããŠãã ããã
移æ€æ§ïŒã¢ããªã±ãŒã·ã§ã³ã³ãŒãã¯ãããŒããŠã§ã¢ã®å å¡«éãå€§å¹ ã«ç°ãªãå Žåã§ãããã¹ãŠã®ããã€ã¹ã§å®è¡ããå¿ èŠããããŸãã çŸåšãARMã«ã¯ããã€ãã®ããŒãžã§ã³ããããŸããVFPãµããŒãã®æç¡ã«ããããããNEONãµããŒãã®æç¡ã«ããããããããŸããŸãªã¬ãžã¹ã¿ã«ãŠã³ã¿ããããŸãã ARMã«å ããŠãx86ã«é¡äŒŒããä»ã®CPUã¢ãŒããã¯ãã£ãç°ãªãGPUãããã«ããŸããŸãªDSPïŒããžã¿ã«ã·ã°ãã«ããã»ããµïŒããããŸãã
ããã©ãŒãã³ã¹ïŒ 2çªç®ã®ç®æšã¯ãå¯æ¬æ§ã®å¶éã䌎ããªãããå¯èœãªæé«ã¬ãã«ã®ããã©ãŒãã³ã¹ãéæããããšã§ãã Renderscriptã«ã€ããŠã¯ãæ¢ã«ã€ã³ã¹ããŒã«ãããŠãããœãªã¥ãŒã·ã§ã³ã«æ¯ã¹ãŠã¯ããã«é«ãããã©ãŒãã³ã¹ãéæããããšããŸããã
ãŠãŒã¶ããªãã£ïŒ 3çªç®ã®ç®æšã¯ãéçºãå¯èœãªéãç°¡çŽ åããããšã§ããã ãæ¥çå€ã³ãŒããã®åºçŸãä»ã®äžå¿ èŠãªéçºè ã®ããŒããåé¿ããããã«ãããã€ãã®éçºã¹ããããå¯èœãªéãèªååããŸããã
ããã3ã€ã®ç®æšã¯èšèšãå¶éããããã€ãã®åŠ¥åããããããŸãã ãããã¯ãRenderscriptãDalvikãNDKãªã©ã®æ¢åã®ãœãªã¥ãŒã·ã§ã³ããåé¢ãããã¬ãŒããªãã§ãã ãããã¯ãããŸããŸãªã¿ã¹ã¯ãå®è¡ããã®ã«åœ¹ç«ã€ããŸããŸãªããŒã«ãšèŠãªãããå¿ èŠããããŸãã
èšèšæ®µéã§ã®äž»ãªæ±ºå®
æåã«æ±ºå®ããå¿ èŠãããã®ã¯ãéçºèšèªã§ãã 䜿çšããèšèªãéžæããå Žåãã»ãšãã©ç¡å¶éã®ãªãã·ã§ã³ã»ããããããŸãã ã·ã§ãŒããŒãããã°ã©ãã³ã°ããããã®èšèªãšããŠãCããã³C ++ãæ€èšãããŸããã ãã®åŸãã·ãŒã³ãªã©ã®ã°ã©ãã£ã«ã«ã¢ããªã±ãŒã·ã§ã³ã®ããŒã¿æ§é ãæäœããå¿ èŠããããããã·ã§ãŒããŒèšèªãæŸæ£ããå¿ èŠããããŸããã ãã€ã³ã¿ãŒã®æ¬ åŠãšååž°ã¯ã䜿ããããã®å¶éãšèŠãªãããŠããŸããã äžæ¹ãC ++ã䜿çšããããšã¯æãŸããããšã§ããã移æ€æ§ã®å¶éã«çŽé¢ããå¿ èŠããããŸãã é«åºŠãªC ++æ©èœã¯ãããã»ããµä»¥å€ã®ããŒããŠã§ã¢ã§å®è¡ããã®ãå°é£ã§ãã ãã®çµæãC99æšæºãRenderscriptã«åºã¥ããŠæ±ºå®ããŸãããããã¯ãæ®ãã®ãœãªã¥ãŒã·ã§ã³ã§åãããã©ãŒãã³ã¹ãæäŸããéçºè ããããããç解ããŠãããããŸããŸãªç°ãªãæ©åšã§å®è¡ããããã«åé¡ãçºçããªãããã§ãã
2çªç®ã®ãã¬ãŒããªãã¯ãRenderscriptã¯ãŒã¯ãããŒèªäœã§ãã ç¹ã«ããœãŒã¹ã³ãŒãããã·ã³ã³ãŒãã«ã³ã³ãã€ã«ããæ¹æ³ã«çŠç¹ãåœãŠãŸããã éçºäžã«ããŸããŸãªãªãã·ã§ã³ãæ€èšããçµæã2ã€ã®ãœãªã¥ãŒã·ã§ã³ãå®è£ ããŸããã å€ãããŒãžã§ã³ïŒEclairãšGingerbreadã®éïŒã¯ãCãœãŒã¹ã³ãŒãããã€ãã£ãã³ãŒãã«å®å šã«ã³ã³ãã€ã«ããŸããã ããã«ãããã¢ããªã±ãŒã·ã§ã³ã«ãã®å Žã§ã³ãŒãçæãªã©ã®æ©èœãæäŸãããŸãããããŠãŒã¶ããªãã£ã®åé¡ã«å€ãããŸããã ã¢ããªã±ãŒã·ã§ã³ãã³ã³ãã€ã«ãã€ã³ã¹ããŒã«ãå®è¡ããŠããæ§æãšã©ãŒãèŠã€ããã®ã¯éåžžã«äžäŸ¿ã§ããã ãŸãã匱ãCPUã¯ãéçåæã®å¯èœæ§ãšå®è¡å¯èœãªæé©åã奪ãããŸããã
次ã«ãLLVMïŒäœã¬ãã«ã®ä»®æ³ãã·ã³ãã¹ã¯ãªããããã©ãããã©ãŒã ã«äŸåããªããã€ãã³ãŒãã«ã³ã³ãã€ã«ããïŒã«åãæ¿ãããã¹ãïŒã¹ã¯ãªãããå®è¡ãããŠããããã€ã¹ïŒã§ã¹ã¯ãªãããã³ã³ãã€ã«ããã³åæããã¢ãã«ã«ç§»åããclangã®ä¿®æ£ããŒãžã§ã³ïŒç¥ã£ãŠãã-ããã¯LLVMã³ã³ãã€ã©ã®ããã³ããšã³ãã§ãïŒã ãã®æ®µéã§ã¯ãããã€ãã®é«åºŠãªæé©åãå®è¡ãããã®åŸLLVMãã€ãã³ãŒããéžæããŸãã äžéãã€ãã³ãŒããããã·ã³ãžã®å€æã¯ãã¹ãã§çºçããŸãïŒããã€ã¹åºæã®æé©åãè¿œå ãããŸãïŒã
èšèšã«ãããæåŸã®äž»èŠãªãã¬ãŒããªãã¯ãã¹ã¬ãããéå§ããããšã§ããã ããã¯ãããã©ãŒãã³ã¹ãšç§»æ€æ§ã®ãã¬ãŒããªãã§ãã ååãªç¥èãããã°ãæ¢åã®ã³ã³ãã¥ãŒãã£ã³ã°ãœãªã¥ãŒã·ã§ã³ã«ãããéçºè ã¯ç¹å®ã®ããŒããŠã§ã¢ãã©ãããã©ãŒã åãã«ã¢ããªã±ãŒã·ã§ã³ãæ§æã§ããŸãããä»ã®ãã©ãããã©ãŒã ã¯äžå©ã«ãªããŸãã æéãšãªãœãŒã¹ã«å¶éããªãå Žåãéçºè ã¯ããŒããŠã§ã¢ã®ä»»æã®çµã¿åããã«åãããŠã¢ããªã±ãŒã·ã§ã³ãã«ã¹ã¿ãã€ãºã§ããŸãã ç¹å®ã®ããã€ã¹ã»ããã®ãã¹ããšãã¥ãŒãã³ã°ã¯æªããããŸãããããŸã ãªãªãŒã¹ãããŠããããéçºè ããå ¥æã§ããªãæ©åšã®ã¢ããªã±ãŒã·ã§ã³ããã¥ãŒãã³ã°ããããšã¯ã§ããŸããã ããããŒã¿ãã«ãªãœãªã¥ãŒã·ã§ã³ã¯ãå®è¡æåæã§ãããããŒã¯æã®ããã©ãŒãã³ã¹ã«ããå¹³åããã©ãŒãã³ã¹ãåäžããŸãã 移æ€æ§ãç§ãã¡ã®æ倧ã®ç®æšã§ããããããã®ãœãªã¥ãŒã·ã§ã³ãéžæããŸããã
å®è¡æã«ã¹ã¬ããã®éå§ãå¶åŸ¡ãããšããéžæã®2çªç®ã®å¹æã¯ãã¹ã¯ãªãããå®è¡ããå Žæã«é¢ããåçãªæ±ºå®ã§ããã ããšãã°ãäžéšã®ã³ã³ãã¥ãŒãã£ã³ã°ããŒããŠã§ã¢ã¯ãã€ã³ã¿ãŒãšååž°ããµããŒãããŠããŸãããä»ã®ããŒããŠã§ã¢ã¯ãµããŒãããŠããŸããã ãŸãããããã®ããšãçŠæ¢ããéçºè ã«APIã®æãäžè¬çãªåæ¯ã®é¡äŒŒæ§ãäžããããšãã§ããŸãããã代ããã«ã©ã³ã¿ã€ã åæãéžæããŸããã ããã«ãããéçºè ã¯ããµããŒããããŠããããŒããŠã§ã¢ã®ãã¹ãŠã®æ©èœã䜿çšã§ããŸãããåæã«ä¿¡é Œã§ããå®å šã«æ©èœããCPUããããŸãã æçµçã«ãéçºè ã¯åªããã¢ããªã±ãŒã·ã§ã³ã®äœæã«éäžã§ããããŒããŠã§ã¢ã¡ãŒã«ãŒã¯ãã«æ©èœã®åŒ·åãªããŒããŠã§ã¢ã«åãçµãããšãã§ããŸãã æ°ããããã©ãŒãã³ã¹åäžã®æ©äŒãçŸãããšããã«ãã¢ããªã±ãŒã·ã§ã³ã¯ã³ãŒããå€æŽããããšãªãããã䜿çšããŸãã
ãŠãŒã¶ããªãã£ã¯ãèšèšæã®äž»ãªç®æšã§ããã æ¢åã®ã»ãšãã©ã®ã³ã³ãã¥ãŒãã£ã³ã°ããã³ã°ã©ãã£ãã¯ã¹ãœãªã¥ãŒã·ã§ã³ã§ã¯ãé«æ§èœã³ãŒããã¢ããªã±ãŒã·ã§ã³ã³ãŒãã«ãªã³ã¯ããããã®ãåºå®ãããžãã¯ãå¿ èŠã§ãã ãã®ãããªã³ãŒãã¯ãšã©ãŒãçºçãããããæžãã®ã«åé¡ããããŸãã ãã¹ãã§Renderscriptã«ãã£ãŠå®è¡ãããéçåæã¯ããã®åé¡ã®è§£æ±ºã«åœ¹ç«ã¡ãŸãã ã¹ã¯ãªããã®åãŠãŒã¶ãŒã¯ãç¬èªã®ãäºãã«çµã³ã€ããDalvikã¯ã©ã¹ãäœæããŸãã æ¥çã¯ã©ã¹ãšãã®ã¢ã¯ã»ããµã®ååã¯ãã¹ã¯ãªãããã掟çããŠããŸãã ããã«ãããDalvikã®ã¹ã¯ãªããã®äœ¿çšãç°¡åã«ãªããŸãã
äŸïŒã¢ããªã±ãŒã·ã§ã³ã¬ãã«
äžèšã®ãã¹ãŠã®ãã¬ãŒããªããèãããšãã³ã³ãã¥ãŒãã£ã³ã°ã¢ããªã±ãŒã·ã§ã³ã®ç°¡åãªäŸã¯ã©ã®ããã«èŠããã¹ãã§ããããïŒ ãã®åºæ¬çãªäŸã§ã¯ãéåžžã®android.graphics.Bitmapãªããžã§ã¯ããååŸããå¥ã®ããããããã«ã³ããŒããã¹ã¯ãªãããå®è¡ãããšåæã«ãã¢ãã¯ãã«å€æããŸãã ã¹ã¯ãªããèªäœãèŠãåã«ãã¹ã¯ãªãããåŒã³åºãã¢ããªã±ãŒã·ã§ã³ã³ãŒããèŠãŠã¿ãŸãããã HelloCompute SDKã®äŸïŒ
private Bitmap mBitmapIn; private Bitmap mBitmapOut; private RenderScript mRS; private Allocation mInAllocation; private Allocation mOutAllocation; private ScriptC_mono mScript; private void createScript() { mRS = RenderScript.create(this); mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType()); mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono); mScript.set_gIn(mInAllocation); mScript.set_gOut(mOutAllocation); mScript.set_gScript(mScript); mScript.invoke_filter(); mOutAllocation.copyTo(mBitmapOut);
ãã®ã¡ãœããã¯ã2ã€ã®ãããããããæ¢ã«äœæãããŠãããåããµã€ãºãšåœ¢åŒãæã£ãŠããããšãåæãšããŠããŸãã Renderscriptã¢ããªã±ãŒã·ã§ã³ãæåã«å¿ èŠãšãããã®ã¯ã³ã³ããã¹ããªããžã§ã¯ãã§ãã ããã¯ãä»ã®Renderscriptãªããžã§ã¯ããäœæããã³ç®¡çããããã«äœ¿çšãããäžå¿çãªãªããžã§ã¯ãã§ãã ã³ãŒãã®æåã®è¡ã¯mRSãªããžã§ã¯ããäœæããŸãããã®ãªããžã§ã¯ãã¯ãã¢ããªã±ãŒã·ã§ã³ããããŸãã¯ããã䜿çšããŠäœæããããªããžã§ã¯ãã䜿çšããéãåç¶ããå¿ èŠããããŸãã
次ã®2ã€ã®æ¹æ³ã«ãããããããããããèšç®çšã®å²ãåœãŠãäœæãããŸãã Renderscriptã«ã¯ç¬èªã®ã¡ã¢ãªã¢ãã±ãŒã¿ããããŸããããã¯ãã¡ã¢ãªãè€æ°ã®ããã»ããµéã§å ±æãããè€æ°ã®ã¡ã¢ãªã¹ããŒã¹ãååšããå¯èœæ§ãé«ãããã§ãã ã¢ãã±ãŒã¿ãäœæããããšããã·ã¹ãã ãç®çã®ã¿ã¹ã¯ã«å¿ èŠãªã¡ã¢ãªã®ã¿ã€ãã決å®ã§ããããã«ãæœåšçãªçšéã«çªå·ãä»ããå¿ èŠããããŸãã
æåã®createFromBitmapïŒïŒã¡ãœããã¯ãé 眮ãäœæããããããããã®ã³ã³ãã³ãããã®äžã«ã³ããŒããŸãã ãã±ãŒã·ã§ã³ã¯ãRenderscriptã䜿çšããã¡ã¢ãªã®åºæ¬åäœã§ãã createTypedïŒïŒã§äœæããã2çªç®ã®ãã¬ãŒã¹ã¡ã³ãã¯ãæåã®ãã¬ãŒã¹ã¡ã³ããšåããã¬ãŒã¹ã¡ã³ããçæããŸãã ããã«ããã®æ§é ã®å®çŸ©ã¯ãæåããã®getTypeïŒïŒèŠæ±ã«ãã£ãŠè¿ãããŸãã Renderscriptã¿ã€ãã¯ã¬ã€ã¢ãŠãæ§é ãå®çŸ©ããŸãã ãã®å Žåãã¿ã€ãã¯ãå ¥åããããããã®é«ããå¹ ãããã³åœ¢åŒã䜿çšããŠçæãããŸãã
次ã®è¡ã¯ãmono.rsããšããã¹ã¯ãªãããããŒãããR.raw.monoã䜿çšããŠååŸããŸãã ã¹ã¯ãªããèªäœã¯ãã¢ããªã±ãŒã·ã§ã³ããã±ãŒãžïŒAPKå ïŒã«çã®ãªãœãŒã¹ãšããŠä¿åãããŸãã çæããããæ¥çãã¯ã©ã¹ã®ååScriptC_monoã«æ³šç®ããŠãã ããã
次ã®è¡ã¯ããgluingãã¯ã©ã¹ã®çæãããã¡ãœããã䜿çšããŠã¹ã¯ãªããããããã£ãèšå®ããŸãã
ããã§ãã¹ãŠã®æºåãæŽããŸããããå®éã«ã¯invoke_filterïŒïŒã¡ãœãããããã€ãã®ä»äºãããŠãããŸããã äžçªäžã®è¡ã¯ããmono.rsãã¹ã¯ãªããèªäœã®filterïŒïŒã¡ãœããã®åŒã³åºãã§ãã ã¡ãœããã«ãã©ã¡ãŒã¿ãŒãããå Žåã¯ãããã«æž¡ãå¿ èŠããããŸãã åŒã³åºãã¯éåæã§ãããããå€ãè¿ãããšã¯çŠæ¢ãããŠããŸãã
æåŸã®è¡ã¯ãã¹ã¯ãªããã®çµæãããããããã«ã³ããŒããŸãã ã¹ã¯ãªããã®å®è¡ãå®äºããããšã確èªããããã«ãããã€ãã®åæã³ãŒããçµã¿èŸŒãŸããŠããŸãã
äŸïŒã¹ã¯ãªãã
äžèšã®ã³ãŒãã«ãã£ãŠåŒã³åºããããmono.rsãã¹ã¯ãªããèªäœã¯æ¬¡ã®ãšããã§ãã
#pragma version(1) #pragma rs java_package_name(com.android.example.hellocompute) rs_allocation gIn; rs_allocation gOut; rs_script gScript; const static float3 gMonoMult = {0.299f, 0.587f, 0.114f}; void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) { float4 f4 = rsUnpackColor8888(*v_in); float3 mono = dot(f4.rgb, gMonoMult); *v_out = rsPackColorTo8888(mono); } void filter() { rsForEach(gScript, gIn, gOut, 0); }
ã¹ã¯ãªããã®æåã®è¡ã¯ãã³ã³ãã€ã©ã«ã©ã®ãªããžã§ã³çšã«æžãããŠããããåã«äŒããŸãã 2è¡ç®ã¯ãçæãããåå°ã³ãŒããšã¢ããªã±ãŒã·ã§ã³ããã±ãŒãžã®é¢é£ä»ããå¶åŸ¡ããŸãã
次ã¯ãå¶åŸ¡ã³ãŒãã§äœæãããå€æ°ã«å¯Ÿå¿ãã3ã€ã®ã°ããŒãã«å€æ°ã§ãã 4çªç®ã®ã°ããŒãã«å€æ°ã¯éçã§ãããããåå°çã§ã¯ãããŸããã ã¹ã¯ãªããã³ãŒãã¯ã³ã³ãããŒã«ãšåæããŠãããããå®æ°ã¯åžžã«éçãšããæ¹ãé©åã§ãã
rootïŒïŒã¡ãœããã¯ãRenderscriptå°çšã§ãã æŠå¿µçã«ã¯ãCã®mainïŒïŒã¡ãœããã«äŒŒãŠããŸããå®è¡æã«ã¹ã¯ãªãããåŒã³åºããããšããã®é¢æ°ããšã³ããªãã€ã³ãã«ãªããŸãã ãã®å Žåããã©ã¡ãŒã¿ãŒã¯ãã¬ãŒã¹ã¡ã³ãã®ãã¯ã»ã«ã§ãã å ±éã®ãŠãŒã¶ãŒãã€ã³ã¿ãŒã«ã¯ããã®åŒã³åºãã«ãã£ãŠåŠçãããŠããå Žæèªäœã®ã¢ãã¬ã¹ãæäŸãããŸãã ãã®äŸã§ã¯ããããã®ãã©ã¡ãŒã¿ãŒã¯ç¡èŠãããŸãã
ã«ãŒãïŒïŒã¡ãœããã®3è¡ã®ã³ãŒãã¯ãRGBA_8888ã®ãã¯ã»ã«ãfloat4ã®ãã¯ãã«ã«è§£åããŸãã 2è¡ç®ã¯ãçµã¿èŸŒã¿æ°åŠé¢æ°dotã䜿çšããŸããããã¯ãã¢ãã¯ãå®æ°ãå ¥åãã¯ã»ã«ãšã¹ã«ã©ãŒç©ãèšç®ããŠãã¢ãã¯ãç»åãååŸããŸãã ãããã¯éåžžã®ãããŒããè¿ãããšã«æ³šæããŠãã ããããããŒãã¯float3ã«å²ãåœãŠãããšãã§ããåã³ã³ããŒãã³ãxãyãzã«å€ãåçŽã«ã³ããŒããŸãã æåŸã«ãçµã¿èŸŒã¿ããŒã«ã䜿çšããŠãå€ãéåžžã®32ããããã¯ã»ã«ã«ããã¯ããŸãã ããã¯ãRGBïŒfloat3ïŒãšRGBAïŒfloat4ïŒã®åœ¢åŒã®ããŒã¿ãåãå ¥ããrsPackColorTo8888ã®ç°ãªãããŒãžã§ã³ããããããã¡ãœããã®ãªãŒããŒããŒãã®äŸã§ããããŸãã
filterïŒïŒã¡ãœããã¯ãå€æãå®è¡ããããã«å¶åŸ¡ã³ãŒãããåŒã³åºãããŸãã åé 眮èŠçŽ ã«å¯ŸããŠèšç®ãå®è¡ããã ãã§ãã æåã®ãã©ã¡ãŒã¿ãŒã¯ãã¹ã¯ãªãããèµ·åãããããšãæå³ããŸããã€ãŸããåé 眮èŠçŽ ã«å¯ŸããŠrootïŒïŒã¡ãœãããåŒã³åºãããŸãã 2çªç®ãš3çªç®ã®ãã©ã¡ãŒã¿ãŒã¯ãå ¥åããã³åºåããŒã¿ã®é 眮ã§ãã æåŸã®ãã©ã¡ãŒã¿ãŒã¯ããŠãŒã¶ãŒããŒã¿ãrootïŒïŒã¡ãœããã«æž¡ãããšãç®çãšããŠããŸãã
forEachã¯ãããã€ã¹äžã«ããå Žåãè€æ°ã®ããã»ããµã§å®è¡ãããŸãã å°æ¥ãforEachã¯ãããããã»ããµããå¥ã®ããã»ããµã«å¶åŸ¡ã移åã§ãã移è¡ãã€ã³ããæäŸã§ããããã«ãªããŸãã ãã®äŸã§ã¯ãå°æ¥ãã£ã«ã¿ãŒïŒïŒãCPUã§å®è¡ãããã«ãŒãïŒïŒãGPUãŸãã¯DSPã§å®è¡ããããšæ³å®ããã®ãåççã§ãã
ããã«ãããRenderscriptã®èšèšã詳ããèŠãŠãç°¡åãªäŸã§ããã®ä»çµã¿ãããç解ã§ããããã«ãªãããšãé¡ã£ãŠããŸãã
翻蚳è ããïŒãã®ãã¯ãããžãŒã®äœ¿çšãäœããã®åœ¢ã§å§ããéçºè ããã®ã³ã¡ã³ããæè¿ããŸãã