Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.renderscript.cts;
     18 
     19 import android.renderscript.Allocation;
     20 import android.renderscript.Element;
     21 import android.renderscript.RenderScript;
     22 import android.renderscript.RenderScript.RSErrorHandler;
     23 import android.renderscript.RSRuntimeException;
     24 import android.renderscript.Type;
     25 import android.util.Log;
     26 import java.util.Random;
     27 import java.util.function.*;
     28 
     29 public class DebugContext extends RSBaseCompute {
     30     Allocation AUnused;
     31     Allocation AInt;
     32     ScriptC_oob Soob;
     33 
     34     boolean mRanErrorHandler = false;
     35     RSErrorHandler mRsError = new RSErrorHandler() {
     36         public void run() {
     37             mRanErrorHandler = true;
     38             Log.e("RenderscriptCTS", mErrorMessage);
     39         }
     40     };
     41 
     42     protected void setupDebugContext() {
     43         mRS.destroy();
     44         mRS = RenderScript.create(mCtx, RenderScript.ContextType.DEBUG);
     45         mRS.setMessageHandler(mRsMessage);
     46         mRS.setErrorHandler(mRsError);
     47 
     48         Soob = new ScriptC_oob(mRS);
     49 
     50         Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
     51         Type t = typeBuilder.setX(1).create();
     52 
     53         AInt = Allocation.createTyped(mRS, t);
     54         Soob.set_aInt(AInt);
     55 
     56         AUnused = Allocation.createTyped(mRS, t);
     57     }
     58 
     59     /**
     60      * Test whether we are detect out-of-bounds allocation accesses
     61      * from an invokable.
     62      */
     63     public void testDebugContextI() {
     64         setupDebugContext();
     65         Soob.invoke_write_i(7, 1);  // Write to invalid location.
     66 
     67         // Flush messages through the pipeline.
     68         mRS.sendMessage(RS_MSG_TEST_FLUSH, null);
     69         waitForMessage();
     70 
     71         Soob.destroy();
     72         assertTrue(mRanErrorHandler);
     73 
     74         // The context is dead at this point so make sure it's not reused
     75         RenderScript.releaseAllContexts();
     76     }
     77 
     78     /**
     79      * Test whether we are detect out-of-bounds allocation accesses
     80      * from a kernel.
     81      */
     82     public void testDebugContextK() {
     83         setupDebugContext();
     84         Soob.forEach_write_k(AUnused);  // Write to invalid location.
     85 
     86         // Flush messages through the pipeline.
     87         mRS.sendMessage(RS_MSG_TEST_FLUSH, null);
     88         waitForMessage();
     89 
     90         Soob.destroy();
     91         assertTrue(mRanErrorHandler);
     92 
     93         // The context is dead at this point so make sure it's not reused
     94         RenderScript.releaseAllContexts();
     95     }
     96 
     97     /**
     98      * Helper for rsAllocationCopy tests
     99      */
    100 
    101     protected class SetupAllocationCopyTests {
    102         int Width;
    103         int Height;
    104         int ArrLen;
    105         Allocation aIn;
    106         Allocation aOut;
    107         Random RN;
    108 
    109         SetupAllocationCopyTests(int dimension,
    110             int size, Function<RenderScript, Type.Builder> TB, long seed) {
    111             // Type.Builder constructor needs a RenderScript instance,
    112             // and that's created by setupDebugContext(). Hence a
    113             // Function<RenderScript, Type.Builder> is needed here
    114 
    115             assertTrue(dimension == 1 || dimension == 2);
    116 
    117             setupDebugContext();
    118             RN = new Random(seed);
    119             // So that we can have offsets that will be invalid in another
    120             // dimension
    121             Width = RN.nextInt(size/2)+size/2;
    122             Height = RN.nextInt(size/2);
    123             if (dimension == 1) {
    124                 ArrLen = Width;
    125             } else {
    126                 ArrLen = Width * Height;
    127             }
    128 
    129             Type.Builder typeBuilder = TB.apply(mRS);
    130 
    131             if (dimension == 1)
    132                 typeBuilder.setX(Width);
    133             else
    134                 typeBuilder.setX(Width).setY(Height);
    135 
    136             aIn = Allocation.createTyped(mRS, typeBuilder.create());
    137             aOut = Allocation.createTyped(mRS, typeBuilder.create());
    138 
    139             // Initialize test Allocations
    140             if (aIn.getElement().getDataType() == Element.DataType.SIGNED_8) {
    141                 byte[] inArray = new byte[ArrLen];
    142                 RN.nextBytes(inArray);
    143                 byte[] outArray = new byte[ArrLen];
    144                 aIn.copyFrom(inArray);
    145                 aOut.copyFrom(outArray);
    146             } else {
    147                 assertTrue(aIn.getElement().getDataType() ==
    148                     Element.DataType.SIGNED_16);
    149                 short[] inArray = new short[ArrLen];
    150                 for (int i = 0; i < ArrLen; i++)
    151                    inArray[i] = (short)RN.nextInt();
    152                 short[] outArray = new short[ArrLen];
    153                 aIn.copyFrom(inArray);
    154                 aOut.copyFrom(outArray);
    155             }
    156 
    157             // Setup script environment
    158             if (dimension == 1) {
    159                 Soob.set_aIn1D(aIn);
    160                 Soob.set_aOut1D(aOut);
    161             } else {
    162                 Soob.set_aIn2D(aIn);
    163                 Soob.set_aOut2D(aOut);
    164             }
    165         }
    166 
    167         protected void finishAllocationCopyTests() {
    168             mRS.finish();
    169 
    170             // Flush messages through the pipeline.
    171             mRS.sendMessage(RS_MSG_TEST_FLUSH, null);
    172             waitForMessage();
    173             Soob.destroy();
    174         }
    175     }
    176 
    177     /**
    178      * 1D copy - things should work under DebugContext if given
    179      * legitimate arguments
    180      */
    181     public void testDebugContextRsAllocationCopy1D_Byte_Normal() {
    182         SetupAllocationCopyTests AC =
    183             new SetupAllocationCopyTests(1, 512,
    184                 (RenderScript rs)-> new Type.Builder(rs, Element.I8(rs)),
    185                 0x172d8ab9);
    186         int Offset = AC.RN.nextInt(AC.Width);
    187         int Count = AC.RN.nextInt(AC.Width - Offset);
    188         Soob.set_dstXOff(Offset);
    189         Soob.set_srcXOff(Offset);
    190         Soob.set_xCount(Count);
    191         Soob.set_srcMip(0);
    192         Soob.set_dstMip(0);
    193         Soob.invoke_test1D();
    194 
    195         AC.finishAllocationCopyTests();
    196 
    197         // Validate results
    198         boolean result = true;
    199         byte[] inArray = new byte[AC.ArrLen];
    200         byte[] outArray = new byte[AC.ArrLen];
    201         AC.aIn.copyTo(inArray);
    202         AC.aOut.copyTo(outArray);
    203         for (int i = 0; i < AC.Width; i++) {
    204             if (Offset <= i && i < Offset + Count) {
    205                 if (inArray[i] != outArray[i]) {
    206                     result = false;
    207                     break;
    208                 }
    209             } else {
    210                 if (outArray[i] != 0) {
    211                     result = false;
    212                     break;
    213                 }
    214             }
    215         }
    216         assertTrue(result);
    217 
    218         RenderScript.releaseAllContexts();
    219     }
    220 
    221     /**
    222      * 2D copy - with legitimate arguments
    223      */
    224     public void testDebugContextRsAllocationCopy2D_Short_Normal() {
    225         SetupAllocationCopyTests AC =
    226             new SetupAllocationCopyTests(2, 128,
    227                 (RenderScript rs)-> new Type.Builder(rs, Element.I16(rs)),
    228                 0x172d8aba);
    229         // to make sure xOff is not a valid yOff.
    230         int xOff = AC.RN.nextInt(AC.Width-AC.Height) + AC.Height;
    231         int yOff = AC.RN.nextInt(AC.Height);
    232         int xCount = AC.RN.nextInt(AC.Width - xOff);
    233         int yCount = AC.RN.nextInt(AC.Height - yOff);
    234 
    235         Soob.set_dstXOff(xOff);
    236         Soob.set_srcXOff(xOff);
    237         Soob.set_yOff(yOff);
    238         Soob.set_xCount(xCount);
    239         Soob.set_yCount(yCount);
    240         Soob.set_srcMip(0);
    241         Soob.set_dstMip(0);
    242         Soob.invoke_test2D();
    243 
    244         AC.finishAllocationCopyTests();
    245 
    246         // Validate results
    247         boolean result = true;
    248         short[] inArray = new short[AC.ArrLen];
    249         short[] outArray = new short[AC.ArrLen];
    250         AC.aIn.copyTo(inArray);
    251         AC.aOut.copyTo(outArray);
    252         for (int i = 0; i < AC.Height; i++) {
    253             for (int j = 0; j < AC.Width; j++) {
    254                 int pos = i * AC.Width + j;
    255                 if (yOff <= i && i < yOff + yCount &&
    256                     xOff <= j && j < xOff + xCount) {
    257                     if (inArray[pos] != outArray[pos]) {
    258                         result = false;
    259                         break;
    260                     }
    261                 } else {
    262                     if (outArray[pos] != 0) {
    263                        result = false;
    264                        break;
    265                     }
    266                 }
    267             }
    268         }
    269         assertTrue(result);
    270 
    271         // The context is dead at this point so make sure it's not reused
    272         RenderScript.releaseAllContexts();
    273     }
    274 
    275     /**
    276      * Test invalid arguments to rsAllocationCopy1D - bad source LOD
    277      */
    278     public void testDebugContextRsAllocationCopy1D_Byte_BadSrcLOD() {
    279         SetupAllocationCopyTests AC =
    280             new SetupAllocationCopyTests(1, 512,
    281                 (RenderScript rs)-> new Type.Builder(rs, Element.I8(rs)),
    282                 0x172d8abb);
    283         int Offset = AC.RN.nextInt(AC.Width);
    284         int Count = AC.RN.nextInt(AC.Width - Offset);
    285         Soob.set_dstXOff(Offset);
    286         Soob.set_srcXOff(Offset);
    287         Soob.set_xCount(Count);
    288         Soob.set_srcMip(1);  // bad source LOD
    289         Soob.set_dstMip(0);
    290         Soob.invoke_test1D();
    291 
    292         AC.finishAllocationCopyTests();
    293         assertTrue(mRanErrorHandler);
    294 
    295         // The context is dead at this point so make sure it's not reused
    296         RenderScript.releaseAllContexts();
    297     }
    298 
    299     /**
    300      * Test invalid arguments to rsAllocationCopy1D - bad destination LOD
    301      */
    302     public void testDebugContextRsAllocationCopy1D_Byte_BadDstLOD() {
    303         SetupAllocationCopyTests AC =
    304             new SetupAllocationCopyTests(1, 512,
    305                 (RenderScript rs)-> new Type.Builder(rs, Element.I8(rs)),
    306                 0x172d8abc);
    307         int Offset = AC.RN.nextInt(AC.Width);
    308         int Count = AC.RN.nextInt(AC.Width - Offset);
    309         Soob.set_dstXOff(Offset);
    310         Soob.set_srcXOff(Offset);
    311         Soob.set_xCount(Count);
    312         Soob.set_srcMip(0);
    313         Soob.set_dstMip(1);  // bad destination LOD
    314         Soob.invoke_test1D();
    315 
    316         AC.finishAllocationCopyTests();
    317         assertTrue(mRanErrorHandler);
    318 
    319         // The context is dead at this point so make sure it's not reused
    320         RenderScript.releaseAllContexts();
    321     }
    322 
    323 
    324     /**
    325      * Test invalid arguments to rsAllocationCopy1D - invalid count
    326      */
    327     public void testDebugContextRsAllocationCopy1D_Byte_BadCount() {
    328         SetupAllocationCopyTests AC =
    329             new SetupAllocationCopyTests(1, 512,
    330                 (RenderScript rs)-> new Type.Builder(rs, Element.I8(rs)),
    331                 0x172d8abd);
    332         int Offset = AC.RN.nextInt(AC.Width);
    333         Soob.set_dstXOff(Offset);
    334         Soob.set_srcXOff(Offset);
    335         Soob.set_xCount(AC.Width - Offset + 1);  // Invalid count by 1
    336         Soob.set_srcMip(0);
    337         Soob.set_dstMip(0);
    338         Soob.invoke_test1D();
    339 
    340         AC.finishAllocationCopyTests();
    341         assertTrue(mRanErrorHandler);
    342 
    343         // The context is dead at this point so make sure it's not reused
    344         RenderScript.releaseAllContexts();
    345     }
    346 
    347     /**
    348      * Test invalid arguments to rsAllocationCopy1D - invalid source offset
    349      */
    350     public void testDebugContextRsAllocationCopy1D_Byte_BadSrcOffset() {
    351         SetupAllocationCopyTests AC =
    352             new SetupAllocationCopyTests(1, 512,
    353                 (RenderScript rs)-> new Type.Builder(rs, Element.I8(rs)),
    354                 0x172d8abe);
    355 
    356         int Offset = AC.RN.nextInt(AC.Width);
    357         Soob.set_dstXOff(Offset);
    358         Soob.set_srcXOff(AC.Width);  // Invalid src offset
    359         Soob.set_xCount(1);
    360         Soob.set_srcMip(0);
    361         Soob.set_dstMip(0);
    362         Soob.invoke_test1D();
    363 
    364         AC.finishAllocationCopyTests();
    365         assertTrue(mRanErrorHandler);
    366 
    367         // The context is dead at this point so make sure it's not reused
    368         RenderScript.releaseAllContexts();
    369     }
    370 
    371     /**
    372      * Test invalid arguments to rsAllocationCopy1D - invalid destination offset
    373      */
    374     public void testDebugContextRsAllocationCopy1D_Byte_BadDstOffset() {
    375         SetupAllocationCopyTests AC =
    376             new SetupAllocationCopyTests(1, 512,
    377                 (RenderScript rs)-> new Type.Builder(rs, Element.I8(rs)),
    378                 0x172d8abf);
    379 
    380         int Offset = AC.RN.nextInt(AC.Width);
    381         Soob.set_dstXOff(AC.ArrLen);  // Invalid dst offset
    382         Soob.set_srcXOff(Offset);  // Invalid src offset
    383         Soob.set_xCount(1);
    384         Soob.set_srcMip(0);
    385         Soob.set_dstMip(0);
    386         Soob.invoke_test1D();
    387 
    388         AC.finishAllocationCopyTests();
    389         assertTrue(mRanErrorHandler);
    390 
    391         // The context is dead at this point so make sure it's not reused
    392         RenderScript.releaseAllContexts();
    393     }
    394 
    395 
    396     /**
    397      * Test invalid arguments to rsAllocationCopy2D - invalid y count
    398      */
    399     public void testDebugContextRsAllocationCopy2D_Short_BadYCount() {
    400         SetupAllocationCopyTests AC =
    401             new SetupAllocationCopyTests(2, 128,
    402                 (RenderScript rs)-> new Type.Builder(rs, Element.I16(rs)),
    403                 0x172d8ac0);
    404         int xOff = AC.RN.nextInt(AC.Width);
    405         int yOff = AC.RN.nextInt(AC.Height);
    406         int xCount = AC.RN.nextInt(AC.Width - xOff);
    407 
    408         Soob.set_dstXOff(xOff);
    409         Soob.set_srcXOff(xOff);
    410         Soob.set_yOff(yOff);
    411         Soob.set_xCount(xCount);  // Legitimate X count
    412         Soob.set_yCount(AC.Height - yOff + 1);  // Invalid Y count by 1
    413         Soob.set_srcMip(0);
    414         Soob.set_dstMip(0);
    415         Soob.invoke_test2D();
    416 
    417         AC.finishAllocationCopyTests();
    418         assertTrue(mRanErrorHandler);
    419 
    420         // The context is dead at this point so make sure it's not reused
    421         RenderScript.releaseAllContexts();
    422     }
    423 
    424     /**
    425      * Test invalid arguments to rsAllocationCopy2D - 2D operation on
    426      * an 1D Allocation
    427      */
    428     public void testDebugContextRsAllocationCopy2D_Short_WrongD() {
    429         setupDebugContext();
    430 
    431         Random random = new Random(0x172d8ac1);
    432         int width = random.nextInt(128);
    433         int height = random.nextInt(128);
    434         int xOff = random.nextInt(width);
    435         int yOff = random.nextInt(height);
    436         int xCount = random.nextInt(width - xOff);
    437         int yCount = random.nextInt(height - yOff);
    438         int arr_len = width * height;
    439 
    440 
    441         Type.Builder typeBuilder1 = new Type.Builder(mRS, Element.I16(mRS));
    442         typeBuilder1.setX(width);
    443         // aIn is one-dimensional
    444         Allocation aIn = Allocation.createTyped(mRS, typeBuilder1.create());
    445         Type.Builder typeBuilder2 = new Type.Builder(mRS, Element.I16(mRS));
    446         typeBuilder2.setX(width).setY(height);
    447         Allocation aOut = Allocation.createTyped(mRS, typeBuilder2.create());
    448 
    449         Soob.set_aIn2D(aIn);
    450         Soob.set_aOut2D(aOut);
    451         Soob.set_srcXOff(xOff);
    452         Soob.set_dstXOff(xOff);
    453         Soob.set_yOff(yOff);
    454         Soob.set_xCount(xCount);  // Legitimate X count
    455         Soob.set_yCount(yCount);  // Legitimate Y count (w.r.t aOut)
    456         Soob.set_srcMip(0);
    457         Soob.set_dstMip(0);
    458         Soob.invoke_test2D();
    459         mRS.finish();
    460 
    461         // Flush messages through the pipeline.
    462         mRS.sendMessage(RS_MSG_TEST_FLUSH, null);
    463         waitForMessage();
    464 
    465         Soob.destroy();
    466         assertTrue(mRanErrorHandler);
    467 
    468         // The context is dead at this point so make sure it's not reused
    469         RenderScript.releaseAllContexts();
    470     }
    471 
    472 
    473 }
    474