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 setupDebugContext()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 */ testDebugContextI()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 */ testDebugContextK()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 SetupAllocationCopyTests(int dimension, int size, Function<RenderScript, Type.Builder> TB, long seed)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 finishAllocationCopyTests()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 */ testDebugContextRsAllocationCopy1D_Byte_Normal()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 */ testDebugContextRsAllocationCopy2D_Short_Normal()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 */ testDebugContextRsAllocationCopy1D_Byte_BadSrcLOD()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 */ testDebugContextRsAllocationCopy1D_Byte_BadDstLOD()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 */ testDebugContextRsAllocationCopy1D_Byte_BadCount()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 */ testDebugContextRsAllocationCopy1D_Byte_BadSrcOffset()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 */ testDebugContextRsAllocationCopy1D_Byte_BadDstOffset()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 */ testDebugContextRsAllocationCopy2D_Short_BadYCount()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 */ testDebugContextRsAllocationCopy2D_Short_WrongD()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