widget/android/AndroidGraphicBuffer.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include <dlfcn.h>
michael@0 7 #include <android/log.h>
michael@0 8 #include <GLES2/gl2.h>
michael@0 9 #include <nsTArray.h>
michael@0 10 #include "AndroidGraphicBuffer.h"
michael@0 11 #include "AndroidBridge.h"
michael@0 12 #include "mozilla/Preferences.h"
michael@0 13
michael@0 14 #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidGraphicBuffer" , ## args)
michael@0 15
michael@0 16 #define EGL_NATIVE_BUFFER_ANDROID 0x3140
michael@0 17 #define EGL_IMAGE_PRESERVED_KHR 0x30D2
michael@0 18
michael@0 19 typedef void *EGLContext;
michael@0 20 typedef void *EGLDisplay;
michael@0 21 typedef uint32_t EGLenum;
michael@0 22 typedef int32_t EGLint;
michael@0 23 typedef uint32_t EGLBoolean;
michael@0 24
michael@0 25 #define EGL_TRUE 1
michael@0 26 #define EGL_FALSE 0
michael@0 27 #define EGL_NONE 0x3038
michael@0 28 #define EGL_NO_CONTEXT (EGLContext)0
michael@0 29 #define EGL_DEFAULT_DISPLAY (void*)0
michael@0 30
michael@0 31 #define ANDROID_LIBUI_PATH "libui.so"
michael@0 32 #define ANDROID_GLES_PATH "libGLESv2.so"
michael@0 33 #define ANDROID_EGL_PATH "libEGL.so"
michael@0 34
michael@0 35 // Really I have no idea, but this should be big enough
michael@0 36 #define GRAPHIC_BUFFER_SIZE 1024
michael@0 37
michael@0 38 enum {
michael@0 39 /* buffer is never read in software */
michael@0 40 GRALLOC_USAGE_SW_READ_NEVER = 0x00000000,
michael@0 41 /* buffer is rarely read in software */
michael@0 42 GRALLOC_USAGE_SW_READ_RARELY = 0x00000002,
michael@0 43 /* buffer is often read in software */
michael@0 44 GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003,
michael@0 45 /* mask for the software read values */
michael@0 46 GRALLOC_USAGE_SW_READ_MASK = 0x0000000F,
michael@0 47
michael@0 48 /* buffer is never written in software */
michael@0 49 GRALLOC_USAGE_SW_WRITE_NEVER = 0x00000000,
michael@0 50 /* buffer is never written in software */
michael@0 51 GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020,
michael@0 52 /* buffer is never written in software */
michael@0 53 GRALLOC_USAGE_SW_WRITE_OFTEN = 0x00000030,
michael@0 54 /* mask for the software write values */
michael@0 55 GRALLOC_USAGE_SW_WRITE_MASK = 0x000000F0,
michael@0 56
michael@0 57 /* buffer will be used as an OpenGL ES texture */
michael@0 58 GRALLOC_USAGE_HW_TEXTURE = 0x00000100,
michael@0 59 /* buffer will be used as an OpenGL ES render target */
michael@0 60 GRALLOC_USAGE_HW_RENDER = 0x00000200,
michael@0 61 /* buffer will be used by the 2D hardware blitter */
michael@0 62 GRALLOC_USAGE_HW_2D = 0x00000400,
michael@0 63 /* buffer will be used with the framebuffer device */
michael@0 64 GRALLOC_USAGE_HW_FB = 0x00001000,
michael@0 65 /* mask for the software usage bit-mask */
michael@0 66 GRALLOC_USAGE_HW_MASK = 0x00001F00,
michael@0 67 };
michael@0 68
michael@0 69 enum {
michael@0 70 HAL_PIXEL_FORMAT_RGBA_8888 = 1,
michael@0 71 HAL_PIXEL_FORMAT_RGBX_8888 = 2,
michael@0 72 HAL_PIXEL_FORMAT_RGB_888 = 3,
michael@0 73 HAL_PIXEL_FORMAT_RGB_565 = 4,
michael@0 74 HAL_PIXEL_FORMAT_BGRA_8888 = 5,
michael@0 75 HAL_PIXEL_FORMAT_RGBA_5551 = 6,
michael@0 76 HAL_PIXEL_FORMAT_RGBA_4444 = 7,
michael@0 77 };
michael@0 78
michael@0 79 typedef struct ARect {
michael@0 80 int32_t left;
michael@0 81 int32_t top;
michael@0 82 int32_t right;
michael@0 83 int32_t bottom;
michael@0 84 } ARect;
michael@0 85
michael@0 86 static bool gTryRealloc = true;
michael@0 87
michael@0 88 static class GLFunctions
michael@0 89 {
michael@0 90 public:
michael@0 91 MOZ_CONSTEXPR GLFunctions() : fGetDisplay(nullptr),
michael@0 92 fEGLGetError(nullptr),
michael@0 93 fCreateImageKHR(nullptr),
michael@0 94 fDestroyImageKHR(nullptr),
michael@0 95 fImageTargetTexture2DOES(nullptr),
michael@0 96 fBindTexture(nullptr),
michael@0 97 fGLGetError(nullptr),
michael@0 98 fGraphicBufferCtor(nullptr),
michael@0 99 fGraphicBufferDtor(nullptr),
michael@0 100 fGraphicBufferLock(nullptr),
michael@0 101 fGraphicBufferLockRect(nullptr),
michael@0 102 fGraphicBufferUnlock(nullptr),
michael@0 103 fGraphicBufferGetNativeBuffer(nullptr),
michael@0 104 fGraphicBufferReallocate(nullptr),
michael@0 105 mInitialized(false)
michael@0 106 {
michael@0 107 }
michael@0 108
michael@0 109 typedef EGLDisplay (* pfnGetDisplay)(void *display_id);
michael@0 110 pfnGetDisplay fGetDisplay;
michael@0 111 typedef EGLint (* pfnEGLGetError)(void);
michael@0 112 pfnEGLGetError fEGLGetError;
michael@0 113
michael@0 114 typedef EGLImageKHR (* pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
michael@0 115 pfnCreateImageKHR fCreateImageKHR;
michael@0 116 typedef EGLBoolean (* pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
michael@0 117 pfnDestroyImageKHR fDestroyImageKHR;
michael@0 118
michael@0 119 typedef void (* pfnImageTargetTexture2DOES)(GLenum target, EGLImageKHR image);
michael@0 120 pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
michael@0 121
michael@0 122 typedef void (* pfnBindTexture)(GLenum target, GLuint texture);
michael@0 123 pfnBindTexture fBindTexture;
michael@0 124
michael@0 125 typedef GLenum (* pfnGLGetError)();
michael@0 126 pfnGLGetError fGLGetError;
michael@0 127
michael@0 128 typedef void (*pfnGraphicBufferCtor)(void*, uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
michael@0 129 pfnGraphicBufferCtor fGraphicBufferCtor;
michael@0 130
michael@0 131 typedef void (*pfnGraphicBufferDtor)(void*);
michael@0 132 pfnGraphicBufferDtor fGraphicBufferDtor;
michael@0 133
michael@0 134 typedef int (*pfnGraphicBufferLock)(void*, uint32_t usage, unsigned char **addr);
michael@0 135 pfnGraphicBufferLock fGraphicBufferLock;
michael@0 136
michael@0 137 typedef int (*pfnGraphicBufferLockRect)(void*, uint32_t usage, const ARect&, unsigned char **addr);
michael@0 138 pfnGraphicBufferLockRect fGraphicBufferLockRect;
michael@0 139
michael@0 140 typedef int (*pfnGraphicBufferUnlock)(void*);
michael@0 141 pfnGraphicBufferUnlock fGraphicBufferUnlock;
michael@0 142
michael@0 143 typedef void* (*pfnGraphicBufferGetNativeBuffer)(void*);
michael@0 144 pfnGraphicBufferGetNativeBuffer fGraphicBufferGetNativeBuffer;
michael@0 145
michael@0 146 typedef int (*pfnGraphicBufferReallocate)(void*, uint32_t w, uint32_t h, uint32_t format);
michael@0 147 pfnGraphicBufferReallocate fGraphicBufferReallocate;
michael@0 148
michael@0 149 bool EnsureInitialized()
michael@0 150 {
michael@0 151 if (mInitialized) {
michael@0 152 return true;
michael@0 153 }
michael@0 154
michael@0 155 void *handle = dlopen(ANDROID_EGL_PATH, RTLD_LAZY);
michael@0 156 if (!handle) {
michael@0 157 LOG("Couldn't load EGL library");
michael@0 158 return false;
michael@0 159 }
michael@0 160
michael@0 161 fGetDisplay = (pfnGetDisplay)dlsym(handle, "eglGetDisplay");
michael@0 162 fEGLGetError = (pfnEGLGetError)dlsym(handle, "eglGetError");
michael@0 163 fCreateImageKHR = (pfnCreateImageKHR)dlsym(handle, "eglCreateImageKHR");
michael@0 164 fDestroyImageKHR = (pfnDestroyImageKHR)dlsym(handle, "eglDestroyImageKHR");
michael@0 165
michael@0 166 if (!fGetDisplay || !fEGLGetError || !fCreateImageKHR || !fDestroyImageKHR) {
michael@0 167 LOG("Failed to find some EGL functions");
michael@0 168 return false;
michael@0 169 }
michael@0 170
michael@0 171 handle = dlopen(ANDROID_GLES_PATH, RTLD_LAZY);
michael@0 172 if (!handle) {
michael@0 173 LOG("Couldn't load GL library");
michael@0 174 return false;
michael@0 175 }
michael@0 176
michael@0 177 fImageTargetTexture2DOES = (pfnImageTargetTexture2DOES)dlsym(handle, "glEGLImageTargetTexture2DOES");
michael@0 178 fBindTexture = (pfnBindTexture)dlsym(handle, "glBindTexture");
michael@0 179 fGLGetError = (pfnGLGetError)dlsym(handle, "glGetError");
michael@0 180
michael@0 181 if (!fImageTargetTexture2DOES || !fBindTexture || !fGLGetError) {
michael@0 182 LOG("Failed to find some GL functions");
michael@0 183 return false;
michael@0 184 }
michael@0 185
michael@0 186 handle = dlopen(ANDROID_LIBUI_PATH, RTLD_LAZY);
michael@0 187 if (!handle) {
michael@0 188 LOG("Couldn't load libui.so");
michael@0 189 return false;
michael@0 190 }
michael@0 191
michael@0 192 fGraphicBufferCtor = (pfnGraphicBufferCtor)dlsym(handle, "_ZN7android13GraphicBufferC1Ejjij");
michael@0 193 fGraphicBufferDtor = (pfnGraphicBufferDtor)dlsym(handle, "_ZN7android13GraphicBufferD1Ev");
michael@0 194 fGraphicBufferLock = (pfnGraphicBufferLock)dlsym(handle, "_ZN7android13GraphicBuffer4lockEjPPv");
michael@0 195 fGraphicBufferLockRect = (pfnGraphicBufferLockRect)dlsym(handle, "_ZN7android13GraphicBuffer4lockEjRKNS_4RectEPPv");
michael@0 196 fGraphicBufferUnlock = (pfnGraphicBufferUnlock)dlsym(handle, "_ZN7android13GraphicBuffer6unlockEv");
michael@0 197 fGraphicBufferGetNativeBuffer = (pfnGraphicBufferGetNativeBuffer)dlsym(handle, "_ZNK7android13GraphicBuffer15getNativeBufferEv");
michael@0 198 fGraphicBufferReallocate = (pfnGraphicBufferReallocate)dlsym(handle, "_ZN7android13GraphicBuffer10reallocateEjjij");
michael@0 199
michael@0 200 if (!fGraphicBufferCtor || !fGraphicBufferDtor || !fGraphicBufferLock ||
michael@0 201 !fGraphicBufferUnlock || !fGraphicBufferGetNativeBuffer) {
michael@0 202 LOG("Failed to lookup some GraphicBuffer functions");
michael@0 203 return false;
michael@0 204 }
michael@0 205
michael@0 206 mInitialized = true;
michael@0 207 return true;
michael@0 208 }
michael@0 209
michael@0 210 private:
michael@0 211 bool mInitialized;
michael@0 212
michael@0 213 } sGLFunctions;
michael@0 214
michael@0 215 namespace mozilla {
michael@0 216
michael@0 217 static void clearGLError()
michael@0 218 {
michael@0 219 while (glGetError() != GL_NO_ERROR);
michael@0 220 }
michael@0 221
michael@0 222 static bool ensureNoGLError(const char* name)
michael@0 223 {
michael@0 224 bool result = true;
michael@0 225 GLuint error;
michael@0 226
michael@0 227 while ((error = glGetError()) != GL_NO_ERROR) {
michael@0 228 LOG("GL error [%s]: %40x\n", name, error);
michael@0 229 result = false;
michael@0 230 }
michael@0 231
michael@0 232 return result;
michael@0 233 }
michael@0 234
michael@0 235 AndroidGraphicBuffer::AndroidGraphicBuffer(uint32_t width, uint32_t height, uint32_t usage,
michael@0 236 gfxImageFormat format) :
michael@0 237 mWidth(width)
michael@0 238 , mHeight(height)
michael@0 239 , mUsage(usage)
michael@0 240 , mFormat(format)
michael@0 241 , mHandle(0)
michael@0 242 , mEGLImage(0)
michael@0 243 {
michael@0 244 }
michael@0 245
michael@0 246 AndroidGraphicBuffer::~AndroidGraphicBuffer()
michael@0 247 {
michael@0 248 DestroyBuffer();
michael@0 249 }
michael@0 250
michael@0 251 void
michael@0 252 AndroidGraphicBuffer::DestroyBuffer()
michael@0 253 {
michael@0 254 /**
michael@0 255 * XXX: eglDestroyImageKHR crashes sometimes due to refcount badness (I think)
michael@0 256 *
michael@0 257 * If you look at egl.cpp (https://github.com/android/platform_frameworks_base/blob/master/opengl/libagl/egl.cpp#L2002)
michael@0 258 * you can see that eglCreateImageKHR just refs the native buffer, and eglDestroyImageKHR
michael@0 259 * just unrefs it. Somehow the ref count gets messed up and things are already destroyed
michael@0 260 * by the time eglDestroyImageKHR gets called. For now, at least, just not calling
michael@0 261 * eglDestroyImageKHR should be fine since we do free the GraphicBuffer below.
michael@0 262 *
michael@0 263 * Bug 712716
michael@0 264 */
michael@0 265 #if 0
michael@0 266 if (mEGLImage) {
michael@0 267 if (sGLFunctions.EnsureInitialized()) {
michael@0 268 sGLFunctions.fDestroyImageKHR(sGLFunctions.fGetDisplay(EGL_DEFAULT_DISPLAY), mEGLImage);
michael@0 269 mEGLImage = nullptr;
michael@0 270 }
michael@0 271 }
michael@0 272 #endif
michael@0 273 mEGLImage = nullptr;
michael@0 274
michael@0 275 if (mHandle) {
michael@0 276 if (sGLFunctions.EnsureInitialized()) {
michael@0 277 sGLFunctions.fGraphicBufferDtor(mHandle);
michael@0 278 }
michael@0 279 free(mHandle);
michael@0 280 mHandle = nullptr;
michael@0 281 }
michael@0 282
michael@0 283 }
michael@0 284
michael@0 285 bool
michael@0 286 AndroidGraphicBuffer::EnsureBufferCreated()
michael@0 287 {
michael@0 288 if (!mHandle) {
michael@0 289 mHandle = malloc(GRAPHIC_BUFFER_SIZE);
michael@0 290 sGLFunctions.fGraphicBufferCtor(mHandle, mWidth, mHeight, GetAndroidFormat(mFormat), GetAndroidUsage(mUsage));
michael@0 291 }
michael@0 292
michael@0 293 return true;
michael@0 294 }
michael@0 295
michael@0 296 bool
michael@0 297 AndroidGraphicBuffer::EnsureInitialized()
michael@0 298 {
michael@0 299 if (!sGLFunctions.EnsureInitialized()) {
michael@0 300 return false;
michael@0 301 }
michael@0 302
michael@0 303 EnsureBufferCreated();
michael@0 304 return true;
michael@0 305 }
michael@0 306
michael@0 307 int
michael@0 308 AndroidGraphicBuffer::Lock(uint32_t aUsage, unsigned char **bits)
michael@0 309 {
michael@0 310 if (!EnsureInitialized())
michael@0 311 return true;
michael@0 312
michael@0 313 return sGLFunctions.fGraphicBufferLock(mHandle, GetAndroidUsage(aUsage), bits);
michael@0 314 }
michael@0 315
michael@0 316 int
michael@0 317 AndroidGraphicBuffer::Lock(uint32_t aUsage, const nsIntRect& aRect, unsigned char **bits)
michael@0 318 {
michael@0 319 if (!EnsureInitialized())
michael@0 320 return false;
michael@0 321
michael@0 322 ARect rect;
michael@0 323 rect.left = aRect.x;
michael@0 324 rect.top = aRect.y;
michael@0 325 rect.right = aRect.x + aRect.width;
michael@0 326 rect.bottom = aRect.y + aRect.height;
michael@0 327
michael@0 328 return sGLFunctions.fGraphicBufferLockRect(mHandle, GetAndroidUsage(aUsage), rect, bits);
michael@0 329 }
michael@0 330
michael@0 331 int
michael@0 332 AndroidGraphicBuffer::Unlock()
michael@0 333 {
michael@0 334 if (!EnsureInitialized())
michael@0 335 return false;
michael@0 336
michael@0 337 return sGLFunctions.fGraphicBufferUnlock(mHandle);
michael@0 338 }
michael@0 339
michael@0 340 bool
michael@0 341 AndroidGraphicBuffer::Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat)
michael@0 342 {
michael@0 343 if (!EnsureInitialized())
michael@0 344 return false;
michael@0 345
michael@0 346 mWidth = aWidth;
michael@0 347 mHeight = aHeight;
michael@0 348 mFormat = aFormat;
michael@0 349
michael@0 350 // Sometimes GraphicBuffer::reallocate just doesn't work. In those cases we'll just allocate a brand
michael@0 351 // new buffer. If reallocate fails once, never try it again.
michael@0 352 if (!gTryRealloc || sGLFunctions.fGraphicBufferReallocate(mHandle, aWidth, aHeight, GetAndroidFormat(aFormat)) != 0) {
michael@0 353 DestroyBuffer();
michael@0 354 EnsureBufferCreated();
michael@0 355
michael@0 356 gTryRealloc = false;
michael@0 357 }
michael@0 358
michael@0 359 return true;
michael@0 360 }
michael@0 361
michael@0 362 uint32_t
michael@0 363 AndroidGraphicBuffer::GetAndroidUsage(uint32_t aUsage)
michael@0 364 {
michael@0 365 uint32_t flags = 0;
michael@0 366
michael@0 367 if (aUsage & UsageSoftwareRead) {
michael@0 368 flags |= GRALLOC_USAGE_SW_READ_OFTEN;
michael@0 369 }
michael@0 370
michael@0 371 if (aUsage & UsageSoftwareWrite) {
michael@0 372 flags |= GRALLOC_USAGE_SW_WRITE_OFTEN;
michael@0 373 }
michael@0 374
michael@0 375 if (aUsage & UsageTexture) {
michael@0 376 flags |= GRALLOC_USAGE_HW_TEXTURE;
michael@0 377 }
michael@0 378
michael@0 379 if (aUsage & UsageTarget) {
michael@0 380 flags |= GRALLOC_USAGE_HW_RENDER;
michael@0 381 }
michael@0 382
michael@0 383 if (aUsage & Usage2D) {
michael@0 384 flags |= GRALLOC_USAGE_HW_2D;
michael@0 385 }
michael@0 386
michael@0 387 return flags;
michael@0 388 }
michael@0 389
michael@0 390 uint32_t
michael@0 391 AndroidGraphicBuffer::GetAndroidFormat(gfxImageFormat aFormat)
michael@0 392 {
michael@0 393 switch (aFormat) {
michael@0 394 case gfxImageFormat::RGB24:
michael@0 395 return HAL_PIXEL_FORMAT_RGBX_8888;
michael@0 396 case gfxImageFormat::RGB16_565:
michael@0 397 return HAL_PIXEL_FORMAT_RGB_565;
michael@0 398 default:
michael@0 399 return 0;
michael@0 400 }
michael@0 401 }
michael@0 402
michael@0 403 bool
michael@0 404 AndroidGraphicBuffer::EnsureEGLImage()
michael@0 405 {
michael@0 406 if (mEGLImage)
michael@0 407 return true;
michael@0 408
michael@0 409
michael@0 410 if (!EnsureInitialized())
michael@0 411 return false;
michael@0 412
michael@0 413 EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };
michael@0 414 void* nativeBuffer = sGLFunctions.fGraphicBufferGetNativeBuffer(mHandle);
michael@0 415
michael@0 416 mEGLImage = sGLFunctions.fCreateImageKHR(sGLFunctions.fGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)nativeBuffer, eglImgAttrs);
michael@0 417 return mEGLImage != nullptr;
michael@0 418 }
michael@0 419
michael@0 420 bool
michael@0 421 AndroidGraphicBuffer::Bind()
michael@0 422 {
michael@0 423 if (!EnsureInitialized())
michael@0 424 return false;
michael@0 425
michael@0 426 if (!EnsureEGLImage()) {
michael@0 427 LOG("No valid EGLImage!");
michael@0 428 return false;
michael@0 429 }
michael@0 430
michael@0 431 clearGLError();
michael@0 432 sGLFunctions.fImageTargetTexture2DOES(GL_TEXTURE_2D, mEGLImage);
michael@0 433 return ensureNoGLError("glEGLImageTargetTexture2DOES");
michael@0 434 }
michael@0 435
michael@0 436 // Build whitelist to check for board type.
michael@0 437 static void InitWhiteList(nsTArray<nsString>& list)
michael@0 438 {
michael@0 439 nsString ele;
michael@0 440 ele.AssignASCII("droid2"); // Motorola Droid 2
michael@0 441 list.AppendElement(ele);
michael@0 442 ele.AssignASCII("GT-I9100"); // Samsung Galaxy SII
michael@0 443 list.AppendElement(ele);
michael@0 444 ele.AssignASCII("herring"); // Samsung Nexus S
michael@0 445 list.AppendElement(ele);
michael@0 446 ele.AssignASCII("omap4sdp"); // Amazon Kindle Fire
michael@0 447 list.AppendElement(ele);
michael@0 448 ele.AssignASCII("SGH-I897"); // Samsung Galaxy S
michael@0 449 list.AppendElement(ele);
michael@0 450 ele.AssignASCII("sgh-i997"); // Samsung Infuse 4G
michael@0 451 list.AppendElement(ele);
michael@0 452 ele.AssignASCII("sgh-t839"); // Samsung Sidekick 4G
michael@0 453 list.AppendElement(ele);
michael@0 454 ele.AssignASCII("shadow"); // Motorola Droid X
michael@0 455 list.AppendElement(ele);
michael@0 456 ele.AssignASCII("spyder"); // Motorola Razr
michael@0 457 list.AppendElement(ele);
michael@0 458 ele.AssignASCII("targa"); // Motorola Droid Bionic
michael@0 459 list.AppendElement(ele);
michael@0 460 ele.AssignASCII("tuna"); // Galaxy Nexus
michael@0 461 list.AppendElement(ele);
michael@0 462 ele.AssignASCII("venus2"); // Motorla Droid Pro
michael@0 463 list.AppendElement(ele);
michael@0 464 }
michael@0 465
michael@0 466 bool
michael@0 467 AndroidGraphicBuffer::IsBlacklisted()
michael@0 468 {
michael@0 469 nsAutoString board;
michael@0 470 if (!AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "BOARD", board))
michael@0 471 return true;
michael@0 472
michael@0 473 NS_ConvertUTF16toUTF8 boardUtf8(board);
michael@0 474
michael@0 475 if (Preferences::GetBool("direct-texture.force.enabled", false)) {
michael@0 476 LOG("allowing board '%s' due to prefs override", boardUtf8.get());
michael@0 477 return false;
michael@0 478 }
michael@0 479
michael@0 480 if (Preferences::GetBool("direct-texture.force.disabled", false)) {
michael@0 481 LOG("disallowing board '%s' due to prefs override", boardUtf8.get());
michael@0 482 return true;
michael@0 483 }
michael@0 484
michael@0 485 static nsTArray<nsString> sListAllowed;
michael@0 486 if (sListAllowed.Length() == 0) {
michael@0 487 InitWhiteList(sListAllowed);
michael@0 488 }
michael@0 489
michael@0 490 int i = -1;
michael@0 491 if ((i = sListAllowed.BinaryIndexOf(board)) >= 0) {
michael@0 492 nsString name = sListAllowed.ElementAt(i);
michael@0 493 LOG("allowing board '%s' based on '%s'\n", boardUtf8.get(), NS_ConvertUTF16toUTF8(name).get());
michael@0 494 return false;
michael@0 495 }
michael@0 496
michael@0 497 LOG("disallowing board: %s\n", boardUtf8.get());
michael@0 498 return true;
michael@0 499 }
michael@0 500
michael@0 501 } /* mozilla */

mercurial