1 /* 2 ** 3 ** Copyright 2007 The Android Open Source Project 4 ** 5 ** Licensed under the Apache License Version 2.0(the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing software 12 ** distributed under the License is distributed on an "AS IS" BASIS 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifdef __arm__ 19 20 #include <assert.h> 21 #include <errno.h> 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <unistd.h> 26 #include <fcntl.h> 27 #include <sys/ioctl.h> 28 #include <sys/types.h> 29 #include <sys/mman.h> 30 31 #include <cutils/log.h> 32 #include <cutils/atomic.h> 33 34 #include <pthread.h> 35 //#include <utils/threads.h> 36 37 #include <EGL/egl.h> 38 #include <EGL/eglext.h> 39 #include <GLES/gl.h> 40 #include <GLES/glext.h> 41 42 #include <pixelflinger/format.h> 43 #include <pixelflinger/pixelflinger.h> 44 //#include "pixelflinger2_format.h" 45 //#include "pixelflinger2_interface.h" 46 47 #include <private/ui/android_natives_priv.h> 48 49 //#include <binder/Parcel.h> 50 #include <surfaceflinger/Surface.h> 51 #include <surfaceflinger/ISurface.h> 52 #include <surfaceflinger/SurfaceComposerClient.h> 53 54 #undef NELEM 55 #define NELEM(x) (sizeof(x)/sizeof(*(x))) 56 57 #define ggl_unlikely(EXP) (EXP) 58 #define ggl_likely(EXP) (EXP) 59 #define min(A,B) ((A)<(B)?(A):(B)) 60 #define max(A,B) ((A)>(B)?(A):(B)) 61 // ---------------------------------------------------------------------------- 62 namespace android 63 { 64 // ---------------------------------------------------------------------------- 65 66 const unsigned int NUM_DISPLAYS = 1; 67 68 static pthread_mutex_t gInitMutex = PTHREAD_MUTEX_INITIALIZER; 69 static pthread_mutex_t gErrorKeyMutex = PTHREAD_MUTEX_INITIALIZER; 70 static pthread_key_t gEGLErrorKey = -1; 71 #ifndef HAVE_ANDROID_OS 72 namespace gl { 73 pthread_key_t gGLKey = -1; 74 }; // namespace gl 75 #endif 76 77 template<typename T> 78 static T setError(GLint error, T returnValue) 79 { 80 if (ggl_unlikely(gEGLErrorKey == -1)) { 81 pthread_mutex_lock(&gErrorKeyMutex); 82 if (gEGLErrorKey == -1) 83 pthread_key_create(&gEGLErrorKey, NULL); 84 pthread_mutex_unlock(&gErrorKeyMutex); 85 } 86 pthread_setspecific(gEGLErrorKey, (void*)error); 87 return returnValue; 88 } 89 90 static GLint getError() 91 { 92 if (ggl_unlikely(gEGLErrorKey == -1)) 93 return EGL_SUCCESS; 94 GLint error = (GLint)pthread_getspecific(gEGLErrorKey); 95 pthread_setspecific(gEGLErrorKey, (void*)EGL_SUCCESS); 96 return error; 97 } 98 99 static struct ogles_context_t * global_ctx; 100 101 struct ogles_context_t { 102 struct context_t { 103 struct egl_context_t* base; 104 } rasterizer; 105 106 unsigned width, height, stride, format; // curret backbuffer 107 void * bits; 108 109 GLenum error; 110 111 static inline ogles_context_t* get() { 112 return global_ctx; 113 } 114 }; 115 116 ogles_context_t * getGlThreadSpecific() 117 { 118 return global_ctx; 119 } 120 void setGlThreadSpecific(ogles_context_t * ctx) 121 { 122 global_ctx = ctx; 123 } 124 125 // ---------------------------------------------------------------------------- 126 127 struct egl_display_t { 128 egl_display_t() : type(0), initialized(0) { } 129 130 static egl_display_t& get_display(EGLDisplay dpy); 131 132 static EGLBoolean is_valid(EGLDisplay dpy) { 133 return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE; 134 } 135 136 NativeDisplayType type; 137 volatile int32_t initialized; 138 }; 139 140 static egl_display_t gDisplays[NUM_DISPLAYS]; 141 142 egl_display_t& egl_display_t::get_display(EGLDisplay dpy) 143 { 144 return gDisplays[uintptr_t(dpy)-1U]; 145 } 146 147 struct egl_context_t { 148 enum { 149 IS_CURRENT = 0x00010000, 150 NEVER_CURRENT = 0x00020000 151 }; 152 uint32_t flags; 153 EGLDisplay dpy; 154 EGLConfig config; 155 EGLSurface read; 156 EGLSurface draw; 157 158 static inline egl_context_t* context(EGLContext ctx) { 159 ogles_context_t* const gl = static_cast<ogles_context_t*>(ctx); 160 return static_cast<egl_context_t*>(gl->rasterizer.base); 161 } 162 }; 163 164 // ---------------------------------------------------------------------------- 165 166 struct egl_surface_t { 167 enum { 168 PAGE_FLIP = 0x00000001, 169 MAGIC = 0x31415265 170 }; 171 172 uint32_t magic; 173 EGLDisplay dpy; 174 EGLConfig config; 175 EGLContext ctx; 176 177 egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat); 178 virtual ~egl_surface_t(); 179 bool isValid() const; 180 virtual bool initCheck() const = 0; 181 182 virtual EGLBoolean bindDrawSurface(ogles_context_t* gl) = 0; 183 //virtual EGLBoolean bindReadSurface(ogles_context_t* gl) = 0; 184 virtual EGLBoolean connect() { 185 return EGL_TRUE; 186 } 187 virtual void disconnect() {} 188 virtual EGLint getWidth() const = 0; 189 virtual EGLint getHeight() const = 0; 190 191 virtual EGLint getHorizontalResolution() const; 192 virtual EGLint getVerticalResolution() const; 193 virtual EGLint getRefreshRate() const; 194 virtual EGLint getSwapBehavior() const; 195 virtual EGLBoolean swapBuffers(); 196 virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); 197 protected: 198 GGLSurface depth; 199 }; 200 201 egl_surface_t::egl_surface_t(EGLDisplay dpy, 202 EGLConfig config, 203 int32_t depthFormat) 204 : magic(MAGIC), dpy(dpy), config(config), ctx(0) 205 { 206 depth.version = sizeof(GGLSurface); 207 depth.data = 0; 208 depth.format = depthFormat; 209 } 210 egl_surface_t::~egl_surface_t() 211 { 212 magic = 0; 213 free(depth.data); 214 } 215 bool egl_surface_t::isValid() const 216 { 217 LOGE_IF(magic != MAGIC, "invalid EGLSurface (%p)", this); 218 return magic == MAGIC; 219 } 220 221 EGLBoolean egl_surface_t::swapBuffers() 222 { 223 return EGL_FALSE; 224 } 225 EGLint egl_surface_t::getHorizontalResolution() const 226 { 227 return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f); 228 } 229 EGLint egl_surface_t::getVerticalResolution() const 230 { 231 return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f); 232 } 233 EGLint egl_surface_t::getRefreshRate() const 234 { 235 return (60 * EGL_DISPLAY_SCALING); 236 } 237 EGLint egl_surface_t::getSwapBehavior() const 238 { 239 return EGL_BUFFER_PRESERVED; 240 } 241 EGLBoolean egl_surface_t::setSwapRectangle( 242 EGLint l, EGLint t, EGLint w, EGLint h) 243 { 244 return EGL_FALSE; 245 } 246 247 // ---------------------------------------------------------------------------- 248 249 struct egl_window_surface_v2_t : public egl_surface_t { 250 egl_window_surface_v2_t( 251 EGLDisplay dpy, EGLConfig config, 252 int32_t depthFormat, 253 ANativeWindow* window); 254 255 ~egl_window_surface_v2_t(); 256 257 virtual bool initCheck() const { 258 return true; // TODO: report failure if ctor fails 259 } 260 virtual EGLBoolean swapBuffers(); 261 virtual EGLBoolean bindDrawSurface(ogles_context_t* gl); 262 //virtual EGLBoolean bindReadSurface(ogles_context_t* gl); 263 virtual EGLBoolean connect(); 264 virtual void disconnect(); 265 virtual EGLint getWidth() const { 266 return width; 267 } 268 virtual EGLint getHeight() const { 269 return height; 270 } 271 virtual EGLint getHorizontalResolution() const; 272 virtual EGLint getVerticalResolution() const; 273 virtual EGLint getRefreshRate() const; 274 virtual EGLint getSwapBehavior() const; 275 virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); 276 277 private: 278 status_t lock(ANativeWindowBuffer* buf, int usage, void** vaddr); 279 status_t unlock(ANativeWindowBuffer* buf); 280 ANativeWindow* nativeWindow; 281 ANativeWindowBuffer* buffer; 282 ANativeWindowBuffer* previousBuffer; 283 gralloc_module_t const* module; 284 int width; 285 int height; 286 void* bits; 287 GGLFormat const* pixelFormatTable; 288 289 struct Rect { 290 inline Rect() { }; 291 inline Rect(int32_t w, int32_t h) 292 : left(0), top(0), right(w), bottom(h) { } 293 inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) 294 : left(l), top(t), right(r), bottom(b) { } 295 Rect& andSelf(const Rect& r) { 296 left = max(left, r.left); 297 top = max(top, r.top); 298 right = min(right, r.right); 299 bottom = min(bottom, r.bottom); 300 return *this; 301 } 302 bool isEmpty() const { 303 return (left>=right || top>=bottom); 304 } 305 void dump(char const* what) { 306 LOGD("%s { %5d, %5d, w=%5d, h=%5d }", 307 what, left, top, right-left, bottom-top); 308 } 309 310 int32_t left; 311 int32_t top; 312 int32_t right; 313 int32_t bottom; 314 }; 315 316 struct Region { 317 inline Region() : count(0) { } 318 typedef Rect const* const_iterator; 319 const_iterator begin() const { 320 return storage; 321 } 322 const_iterator end() const { 323 return storage+count; 324 } 325 static Region subtract(const Rect& lhs, const Rect& rhs) { 326 Region reg; 327 Rect* storage = reg.storage; 328 if (!lhs.isEmpty()) { 329 if (lhs.top < rhs.top) { // top rect 330 storage->left = lhs.left; 331 storage->top = lhs.top; 332 storage->right = lhs.right; 333 storage->bottom = rhs.top; 334 storage++; 335 } 336 const int32_t top = max(lhs.top, rhs.top); 337 const int32_t bot = min(lhs.bottom, rhs.bottom); 338 if (top < bot) { 339 if (lhs.left < rhs.left) { // left-side rect 340 storage->left = lhs.left; 341 storage->top = top; 342 storage->right = rhs.left; 343 storage->bottom = bot; 344 storage++; 345 } 346 if (lhs.right > rhs.right) { // right-side rect 347 storage->left = rhs.right; 348 storage->top = top; 349 storage->right = lhs.right; 350 storage->bottom = bot; 351 storage++; 352 } 353 } 354 if (lhs.bottom > rhs.bottom) { // bottom rect 355 storage->left = lhs.left; 356 storage->top = rhs.bottom; 357 storage->right = lhs.right; 358 storage->bottom = lhs.bottom; 359 storage++; 360 } 361 reg.count = storage - reg.storage; 362 } 363 return reg; 364 } 365 bool isEmpty() const { 366 return count<=0; 367 } 368 private: 369 Rect storage[4]; 370 ssize_t count; 371 }; 372 373 void copyBlt( 374 ANativeWindowBuffer* dst, void* dst_vaddr, 375 ANativeWindowBuffer* src, void const* src_vaddr, 376 const Region& clip); 377 378 Rect dirtyRegion; 379 Rect oldDirtyRegion; 380 }; 381 382 egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, 383 EGLConfig config, 384 int32_t depthFormat, 385 ANativeWindow* window) 386 : egl_surface_t(dpy, config, depthFormat), 387 nativeWindow(window), buffer(0), previousBuffer(0), module(0), 388 bits(NULL) 389 { 390 hw_module_t const* pModule; 391 hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); 392 module = reinterpret_cast<gralloc_module_t const*>(pModule); 393 394 pixelFormatTable = gglGetPixelFormatTable(); 395 396 // keep a reference on the window 397 nativeWindow->common.incRef(&nativeWindow->common); 398 nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &width); 399 nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &height); 400 } 401 402 egl_window_surface_v2_t::~egl_window_surface_v2_t() 403 { 404 if (buffer) { 405 buffer->common.decRef(&buffer->common); 406 } 407 if (previousBuffer) { 408 previousBuffer->common.decRef(&previousBuffer->common); 409 } 410 nativeWindow->common.decRef(&nativeWindow->common); 411 } 412 413 EGLBoolean egl_window_surface_v2_t::connect() 414 { 415 // we're intending to do software rendering 416 native_window_set_usage(nativeWindow, 417 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); 418 419 // dequeue a buffer 420 if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { 421 return setError(EGL_BAD_ALLOC, EGL_FALSE); 422 } 423 424 // allocate a corresponding depth-buffer 425 width = buffer->width; 426 height = buffer->height; 427 if (depth.format) { 428 depth.width = width; 429 depth.height = height; 430 depth.stride = depth.width; // use the width here 431 depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); 432 if (depth.data == 0) { 433 return setError(EGL_BAD_ALLOC, EGL_FALSE); 434 } 435 } 436 437 // keep a reference on the buffer 438 buffer->common.incRef(&buffer->common); 439 440 // Lock the buffer 441 nativeWindow->lockBuffer(nativeWindow, buffer); 442 // pin the buffer down 443 if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | 444 GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { 445 LOGE("connect() failed to lock buffer %p (%ux%u)", 446 buffer, buffer->width, buffer->height); 447 return setError(EGL_BAD_ACCESS, EGL_FALSE); 448 // FIXME: we should make sure we're not accessing the buffer anymore 449 } 450 return EGL_TRUE; 451 } 452 453 void egl_window_surface_v2_t::disconnect() 454 { 455 if (buffer && bits) { 456 bits = NULL; 457 unlock(buffer); 458 } 459 // enqueue the last frame 460 nativeWindow->queueBuffer(nativeWindow, buffer); 461 if (buffer) { 462 buffer->common.decRef(&buffer->common); 463 buffer = 0; 464 } 465 if (previousBuffer) { 466 previousBuffer->common.decRef(&previousBuffer->common); 467 previousBuffer = 0; 468 } 469 } 470 471 status_t egl_window_surface_v2_t::lock( 472 ANativeWindowBuffer* buf, int usage, void** vaddr) 473 { 474 int err; 475 476 err = module->lock(module, buf->handle, 477 usage, 0, 0, buf->width, buf->height, vaddr); 478 479 return err; 480 } 481 482 status_t egl_window_surface_v2_t::unlock(ANativeWindowBuffer* buf) 483 { 484 if (!buf) return BAD_VALUE; 485 int err = NO_ERROR; 486 487 err = module->unlock(module, buf->handle); 488 489 return err; 490 } 491 492 void egl_window_surface_v2_t::copyBlt( 493 ANativeWindowBuffer* dst, void* dst_vaddr, 494 ANativeWindowBuffer* src, void const* src_vaddr, 495 const Region& clip) 496 { 497 // FIXME: use copybit if possible 498 // NOTE: dst and src must be the same format 499 500 Region::const_iterator cur = clip.begin(); 501 Region::const_iterator end = clip.end(); 502 503 const size_t bpp = pixelFormatTable[src->format].size; 504 const size_t dbpr = dst->stride * bpp; 505 const size_t sbpr = src->stride * bpp; 506 507 uint8_t const * const src_bits = (uint8_t const *)src_vaddr; 508 uint8_t * const dst_bits = (uint8_t *)dst_vaddr; 509 510 while (cur != end) { 511 const Rect& r(*cur++); 512 ssize_t w = r.right - r.left; 513 ssize_t h = r.bottom - r.top; 514 if (w <= 0 || h<=0) continue; 515 size_t size = w * bpp; 516 uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; 517 uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; 518 if (dbpr==sbpr && size==sbpr) { 519 size *= h; 520 h = 1; 521 } 522 do { 523 memcpy(d, s, size); 524 d += dbpr; 525 s += sbpr; 526 } while (--h > 0); 527 } 528 } 529 530 EGLBoolean egl_window_surface_v2_t::swapBuffers() 531 { 532 if (!buffer) { 533 return setError(EGL_BAD_ACCESS, EGL_FALSE); 534 } 535 536 /* 537 * Handle eglSetSwapRectangleANDROID() 538 * We copyback from the front buffer 539 */ 540 if (!dirtyRegion.isEmpty()) { 541 dirtyRegion.andSelf(Rect(buffer->width, buffer->height)); 542 if (previousBuffer) { 543 // This was const Region copyBack, but that causes an 544 // internal compile error on simulator builds 545 /*const*/ 546 Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); 547 if (!copyBack.isEmpty()) { 548 void* prevBits; 549 if (lock(previousBuffer, 550 GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) { 551 // copy from previousBuffer to buffer 552 copyBlt(buffer, bits, previousBuffer, prevBits, copyBack); 553 unlock(previousBuffer); 554 } 555 } 556 } 557 oldDirtyRegion = dirtyRegion; 558 } 559 560 if (previousBuffer) { 561 previousBuffer->common.decRef(&previousBuffer->common); 562 previousBuffer = 0; 563 } 564 565 unlock(buffer); 566 previousBuffer = buffer; 567 nativeWindow->queueBuffer(nativeWindow, buffer); 568 buffer = 0; 569 570 // dequeue a new buffer 571 if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) == NO_ERROR) { 572 573 // TODO: lockBuffer should rather be executed when the very first 574 // direct rendering occurs. 575 nativeWindow->lockBuffer(nativeWindow, buffer); 576 577 // reallocate the depth-buffer if needed 578 if ((width != buffer->width) || (height != buffer->height)) { 579 // TODO: we probably should reset the swap rect here 580 // if the window size has changed 581 width = buffer->width; 582 height = buffer->height; 583 if (depth.data) { 584 free(depth.data); 585 depth.width = width; 586 depth.height = height; 587 depth.stride = buffer->stride; 588 depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); 589 if (depth.data == 0) { 590 setError(EGL_BAD_ALLOC, EGL_FALSE); 591 return EGL_FALSE; 592 } 593 } 594 } 595 596 // keep a reference on the buffer 597 buffer->common.incRef(&buffer->common); 598 599 // finally pin the buffer down 600 if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | 601 GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { 602 LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", 603 buffer, buffer->width, buffer->height); 604 return setError(EGL_BAD_ACCESS, EGL_FALSE); 605 // FIXME: we should make sure we're not accessing the buffer anymore 606 } 607 } else { 608 return setError(EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 609 } 610 611 return EGL_TRUE; 612 } 613 614 EGLBoolean egl_window_surface_v2_t::setSwapRectangle( 615 EGLint l, EGLint t, EGLint w, EGLint h) 616 { 617 dirtyRegion = Rect(l, t, l+w, t+h); 618 return EGL_TRUE; 619 } 620 621 EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) 622 { 623 GGLSurface buffer; 624 buffer.version = sizeof(GGLSurface); 625 buffer.width = this->buffer->width; 626 buffer.height = this->buffer->height; 627 buffer.stride = this->buffer->stride; 628 buffer.data = (GGLubyte*)bits; 629 buffer.format = this->buffer->format; 630 631 //puts("egl_window_surface_v2_t::bindDrawSurface"); 632 //printf("\t width=%d height=%d stride=%d format=%d \n", buffer.width, buffer.height, buffer.stride, buffer.format); 633 634 gl->width = this->buffer->width; 635 gl->height = this->buffer->height; 636 gl->stride = this->buffer->stride; 637 gl->format = this->buffer->format; 638 gl->bits = bits; 639 640 //gl->rasterizer.procs.colorBuffer(gl, &buffer); 641 //if (depth.data != gl->rasterizer.state.buffers.depth.data) 642 // gl->rasterizer.procs.depthBuffer(gl, &depth); 643 return EGL_TRUE; 644 } 645 EGLint egl_window_surface_v2_t::getHorizontalResolution() const 646 { 647 return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f); 648 } 649 EGLint egl_window_surface_v2_t::getVerticalResolution() const 650 { 651 return (nativeWindow->ydpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f); 652 } 653 EGLint egl_window_surface_v2_t::getRefreshRate() const 654 { 655 return (60 * EGL_DISPLAY_SCALING); // FIXME 656 } 657 EGLint egl_window_surface_v2_t::getSwapBehavior() const 658 { 659 /* 660 * EGL_BUFFER_PRESERVED means that eglSwapBuffers() completely preserves 661 * the content of the swapped buffer. 662 * 663 * EGL_BUFFER_DESTROYED means that the content of the buffer is lost. 664 * 665 * However when ANDROID_swap_retcangle is supported, EGL_BUFFER_DESTROYED 666 * only applies to the area specified by eglSetSwapRectangleANDROID(), that 667 * is, everything outside of this area is preserved. 668 * 669 * This implementation of EGL assumes the later case. 670 * 671 */ 672 673 return EGL_BUFFER_DESTROYED; 674 } 675 676 // ---------------------------------------------------------------------------- 677 678 struct egl_pixmap_surface_t : public egl_surface_t { 679 egl_pixmap_surface_t( 680 EGLDisplay dpy, EGLConfig config, 681 int32_t depthFormat, 682 egl_native_pixmap_t const * pixmap); 683 684 virtual ~egl_pixmap_surface_t() { } 685 686 virtual bool initCheck() const { 687 return !depth.format || depth.data!=0; 688 } 689 virtual EGLBoolean bindDrawSurface(ogles_context_t* gl); 690 //virtual EGLBoolean bindReadSurface(ogles_context_t* gl); 691 virtual EGLint getWidth() const { 692 return nativePixmap.width; 693 } 694 virtual EGLint getHeight() const { 695 return nativePixmap.height; 696 } 697 private: 698 egl_native_pixmap_t nativePixmap; 699 }; 700 701 egl_pixmap_surface_t::egl_pixmap_surface_t(EGLDisplay dpy, 702 EGLConfig config, 703 int32_t depthFormat, 704 egl_native_pixmap_t const * pixmap) 705 : egl_surface_t(dpy, config, depthFormat), nativePixmap(*pixmap) 706 { 707 if (depthFormat) { 708 depth.width = pixmap->width; 709 depth.height = pixmap->height; 710 depth.stride = depth.width; // use the width here 711 depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); 712 if (depth.data == 0) { 713 setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); 714 } 715 } 716 } 717 EGLBoolean egl_pixmap_surface_t::bindDrawSurface(ogles_context_t* gl) 718 { 719 puts("egl_pixmap_surface_t::bindDrawSurface"); 720 GGLSurface buffer; 721 buffer.version = sizeof(GGLSurface); 722 buffer.width = nativePixmap.width; 723 buffer.height = nativePixmap.height; 724 buffer.stride = nativePixmap.stride; 725 buffer.data = nativePixmap.data; 726 buffer.format = nativePixmap.format; 727 728 //gl->rasterizer.procs.colorBuffer(gl, &buffer); 729 //if (depth.data != gl->rasterizer.state.buffers.depth.data) 730 // gl->rasterizer.procs.depthBuffer(gl, &depth); 731 return EGL_TRUE; 732 } 733 734 // ---------------------------------------------------------------------------- 735 736 struct egl_pbuffer_surface_t : public egl_surface_t { 737 egl_pbuffer_surface_t( 738 EGLDisplay dpy, EGLConfig config, int32_t depthFormat, 739 int32_t w, int32_t h, int32_t f); 740 741 virtual ~egl_pbuffer_surface_t(); 742 743 virtual bool initCheck() const { 744 return pbuffer.data != 0; 745 } 746 virtual EGLBoolean bindDrawSurface(ogles_context_t* gl); 747 //virtual EGLBoolean bindReadSurface(ogles_context_t* gl); 748 virtual EGLint getWidth() const { 749 return pbuffer.width; 750 } 751 virtual EGLint getHeight() const { 752 return pbuffer.height; 753 } 754 private: 755 GGLSurface pbuffer; 756 }; 757 758 egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, 759 EGLConfig config, int32_t depthFormat, 760 int32_t w, int32_t h, int32_t f) 761 : egl_surface_t(dpy, config, depthFormat) 762 { 763 size_t size = w*h; 764 switch (f) { 765 case GGL_PIXEL_FORMAT_A_8: 766 size *= 1; 767 break; 768 case GGL_PIXEL_FORMAT_RGB_565: 769 size *= 2; 770 break; 771 case GGL_PIXEL_FORMAT_RGBA_8888: 772 size *= 4; 773 break; 774 case GGL_PIXEL_FORMAT_RGBX_8888: 775 size *= 4; 776 break; 777 default: 778 LOGE("incompatible pixel format for pbuffer (format=%d)", f); 779 pbuffer.data = 0; 780 break; 781 } 782 pbuffer.version = sizeof(GGLSurface); 783 pbuffer.width = w; 784 pbuffer.height = h; 785 pbuffer.stride = w; 786 pbuffer.data = (GGLubyte*)malloc(size); 787 pbuffer.format = f; 788 789 if (depthFormat) { 790 depth.width = pbuffer.width; 791 depth.height = pbuffer.height; 792 depth.stride = depth.width; // use the width here 793 depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); 794 if (depth.data == 0) { 795 setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); 796 return; 797 } 798 } 799 } 800 egl_pbuffer_surface_t::~egl_pbuffer_surface_t() 801 { 802 free(pbuffer.data); 803 } 804 EGLBoolean egl_pbuffer_surface_t::bindDrawSurface(ogles_context_t* gl) 805 { 806 puts("egl_pbuffer_surface_t::bindDrawSurface"); 807 //gl->rasterizer.procs.colorBuffer(gl, &pbuffer); 808 //if (depth.data != gl->rasterizer.state.buffers.depth.data) 809 // gl->rasterizer.procs.depthBuffer(gl, &depth); 810 return EGL_TRUE; 811 } 812 813 // ---------------------------------------------------------------------------- 814 815 struct config_pair_t { 816 GLint key; 817 GLint value; 818 }; 819 820 struct configs_t { 821 const config_pair_t* array; 822 int size; 823 }; 824 825 struct config_management_t { 826 GLint key; 827 bool (*match)(GLint reqValue, GLint confValue); 828 static bool atLeast(GLint reqValue, GLint confValue) { 829 return (reqValue == EGL_DONT_CARE) || (confValue >= reqValue); 830 } 831 static bool exact(GLint reqValue, GLint confValue) { 832 return (reqValue == EGL_DONT_CARE) || (confValue == reqValue); 833 } 834 static bool mask(GLint reqValue, GLint confValue) { 835 return (confValue & reqValue) == reqValue; 836 } 837 static bool ignore(GLint reqValue, GLint confValue) { 838 return true; 839 } 840 }; 841 842 // ---------------------------------------------------------------------------- 843 844 #define VERSION_MAJOR 1 845 #define VERSION_MINOR 2 846 static char const * const gVendorString = "Google Inc."; 847 static char const * const gVersionString = "1.2 Android Driver 1.2.0"; 848 static char const * const gClientApiString = "OpenGL ES"; 849 static char const * const gExtensionsString = 850 "EGL_KHR_image_base " 851 // "KHR_image_pixmap " 852 "EGL_ANDROID_image_native_buffer " 853 "EGL_ANDROID_swap_rectangle " 854 ; 855 856 // ---------------------------------------------------------------------------- 857 858 struct extention_map_t { 859 const char * const name; 860 __eglMustCastToProperFunctionPointerType address; 861 }; 862 863 static const extention_map_t gExtentionMap[] = {}; 864 865 /* 866 * In the lists below, attributes names MUST be sorted. 867 * Additionally, all configs must be sorted according to 868 * the EGL specification. 869 */ 870 871 static config_pair_t const config_base_attribute_list[] = { 872 { EGL_STENCIL_SIZE, 0 }, 873 { EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG }, 874 { EGL_LEVEL, 0 }, 875 { EGL_MAX_PBUFFER_HEIGHT, GGL_MAX_VIEWPORT_DIMS }, 876 { EGL_MAX_PBUFFER_PIXELS, 877 GGL_MAX_VIEWPORT_DIMS*GGL_MAX_VIEWPORT_DIMS }, 878 { EGL_MAX_PBUFFER_WIDTH, GGL_MAX_VIEWPORT_DIMS }, 879 { EGL_NATIVE_RENDERABLE, EGL_TRUE }, 880 { EGL_NATIVE_VISUAL_ID, 0 }, 881 { EGL_NATIVE_VISUAL_TYPE, GGL_PIXEL_FORMAT_RGB_565 }, 882 { EGL_SAMPLES, 0 }, 883 { EGL_SAMPLE_BUFFERS, 0 }, 884 { EGL_TRANSPARENT_TYPE, EGL_NONE }, 885 { EGL_TRANSPARENT_BLUE_VALUE, 0 }, 886 { EGL_TRANSPARENT_GREEN_VALUE, 0 }, 887 { EGL_TRANSPARENT_RED_VALUE, 0 }, 888 { EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE }, 889 { EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE }, 890 { EGL_MIN_SWAP_INTERVAL, 1 }, 891 { EGL_MAX_SWAP_INTERVAL, 1 }, 892 { EGL_LUMINANCE_SIZE, 0 }, 893 { EGL_ALPHA_MASK_SIZE, 0 }, 894 { EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER }, 895 { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT }, 896 { EGL_CONFORMANT, 0 } 897 }; 898 899 // These configs can override the base attribute list 900 // NOTE: when adding a config here, don't forget to update eglCreate*Surface() 901 902 // 565 configs 903 static config_pair_t const config_0_attribute_list[] = { 904 { EGL_BUFFER_SIZE, 16 }, 905 { EGL_ALPHA_SIZE, 0 }, 906 { EGL_BLUE_SIZE, 5 }, 907 { EGL_GREEN_SIZE, 6 }, 908 { EGL_RED_SIZE, 5 }, 909 { EGL_DEPTH_SIZE, 0 }, 910 { EGL_CONFIG_ID, 0 }, 911 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 }, 912 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 913 }; 914 915 static config_pair_t const config_1_attribute_list[] = { 916 { EGL_BUFFER_SIZE, 16 }, 917 { EGL_ALPHA_SIZE, 0 }, 918 { EGL_BLUE_SIZE, 5 }, 919 { EGL_GREEN_SIZE, 6 }, 920 { EGL_RED_SIZE, 5 }, 921 { EGL_DEPTH_SIZE, 16 }, 922 { EGL_CONFIG_ID, 1 }, 923 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 }, 924 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 925 }; 926 927 // RGB 888 configs 928 static config_pair_t const config_2_attribute_list[] = { 929 { EGL_BUFFER_SIZE, 32 }, 930 { EGL_ALPHA_SIZE, 0 }, 931 { EGL_BLUE_SIZE, 8 }, 932 { EGL_GREEN_SIZE, 8 }, 933 { EGL_RED_SIZE, 8 }, 934 { EGL_DEPTH_SIZE, 0 }, 935 { EGL_CONFIG_ID, 6 }, 936 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 }, 937 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 938 }; 939 940 static config_pair_t const config_3_attribute_list[] = { 941 { EGL_BUFFER_SIZE, 32 }, 942 { EGL_ALPHA_SIZE, 0 }, 943 { EGL_BLUE_SIZE, 8 }, 944 { EGL_GREEN_SIZE, 8 }, 945 { EGL_RED_SIZE, 8 }, 946 { EGL_DEPTH_SIZE, 16 }, 947 { EGL_CONFIG_ID, 7 }, 948 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 }, 949 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 950 }; 951 952 // 8888 configs 953 static config_pair_t const config_4_attribute_list[] = { 954 { EGL_BUFFER_SIZE, 32 }, 955 { EGL_ALPHA_SIZE, 8 }, 956 { EGL_BLUE_SIZE, 8 }, 957 { EGL_GREEN_SIZE, 8 }, 958 { EGL_RED_SIZE, 8 }, 959 { EGL_DEPTH_SIZE, 0 }, 960 { EGL_CONFIG_ID, 2 }, 961 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 }, 962 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 963 }; 964 965 static config_pair_t const config_5_attribute_list[] = { 966 { EGL_BUFFER_SIZE, 32 }, 967 { EGL_ALPHA_SIZE, 8 }, 968 { EGL_BLUE_SIZE, 8 }, 969 { EGL_GREEN_SIZE, 8 }, 970 { EGL_RED_SIZE, 8 }, 971 { EGL_DEPTH_SIZE, 16 }, 972 { EGL_CONFIG_ID, 3 }, 973 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 }, 974 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 975 }; 976 977 // A8 configs 978 static config_pair_t const config_6_attribute_list[] = { 979 { EGL_BUFFER_SIZE, 8 }, 980 { EGL_ALPHA_SIZE, 8 }, 981 { EGL_BLUE_SIZE, 0 }, 982 { EGL_GREEN_SIZE, 0 }, 983 { EGL_RED_SIZE, 0 }, 984 { EGL_DEPTH_SIZE, 0 }, 985 { EGL_CONFIG_ID, 4 }, 986 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 }, 987 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 988 }; 989 990 static config_pair_t const config_7_attribute_list[] = { 991 { EGL_BUFFER_SIZE, 8 }, 992 { EGL_ALPHA_SIZE, 8 }, 993 { EGL_BLUE_SIZE, 0 }, 994 { EGL_GREEN_SIZE, 0 }, 995 { EGL_RED_SIZE, 0 }, 996 { EGL_DEPTH_SIZE, 16 }, 997 { EGL_CONFIG_ID, 5 }, 998 { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 }, 999 { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, 1000 }; 1001 1002 static configs_t const gConfigs[] = { 1003 { config_0_attribute_list, NELEM(config_0_attribute_list) }, 1004 { config_1_attribute_list, NELEM(config_1_attribute_list) }, 1005 { config_2_attribute_list, NELEM(config_2_attribute_list) }, 1006 { config_3_attribute_list, NELEM(config_3_attribute_list) }, 1007 { config_4_attribute_list, NELEM(config_4_attribute_list) }, 1008 { config_5_attribute_list, NELEM(config_5_attribute_list) }, 1009 { config_6_attribute_list, NELEM(config_6_attribute_list) }, 1010 { config_7_attribute_list, NELEM(config_7_attribute_list) }, 1011 }; 1012 1013 static config_management_t const gConfigManagement[] = { 1014 { EGL_BUFFER_SIZE, config_management_t::atLeast }, 1015 { EGL_ALPHA_SIZE, config_management_t::atLeast }, 1016 { EGL_BLUE_SIZE, config_management_t::atLeast }, 1017 { EGL_GREEN_SIZE, config_management_t::atLeast }, 1018 { EGL_RED_SIZE, config_management_t::atLeast }, 1019 { EGL_DEPTH_SIZE, config_management_t::atLeast }, 1020 { EGL_STENCIL_SIZE, config_management_t::atLeast }, 1021 { EGL_CONFIG_CAVEAT, config_management_t::exact }, 1022 { EGL_CONFIG_ID, config_management_t::exact }, 1023 { EGL_LEVEL, config_management_t::exact }, 1024 { EGL_MAX_PBUFFER_HEIGHT, config_management_t::ignore }, 1025 { EGL_MAX_PBUFFER_PIXELS, config_management_t::ignore }, 1026 { EGL_MAX_PBUFFER_WIDTH, config_management_t::ignore }, 1027 { EGL_NATIVE_RENDERABLE, config_management_t::exact }, 1028 { EGL_NATIVE_VISUAL_ID, config_management_t::ignore }, 1029 { EGL_NATIVE_VISUAL_TYPE, config_management_t::exact }, 1030 { EGL_SAMPLES, config_management_t::exact }, 1031 { EGL_SAMPLE_BUFFERS, config_management_t::exact }, 1032 { EGL_SURFACE_TYPE, config_management_t::mask }, 1033 { EGL_TRANSPARENT_TYPE, config_management_t::exact }, 1034 { EGL_TRANSPARENT_BLUE_VALUE, config_management_t::exact }, 1035 { EGL_TRANSPARENT_GREEN_VALUE, config_management_t::exact }, 1036 { EGL_TRANSPARENT_RED_VALUE, config_management_t::exact }, 1037 { EGL_BIND_TO_TEXTURE_RGBA, config_management_t::exact }, 1038 { EGL_BIND_TO_TEXTURE_RGB, config_management_t::exact }, 1039 { EGL_MIN_SWAP_INTERVAL, config_management_t::exact }, 1040 { EGL_MAX_SWAP_INTERVAL, config_management_t::exact }, 1041 { EGL_LUMINANCE_SIZE, config_management_t::atLeast }, 1042 { EGL_ALPHA_MASK_SIZE, config_management_t::atLeast }, 1043 { EGL_COLOR_BUFFER_TYPE, config_management_t::exact }, 1044 { EGL_RENDERABLE_TYPE, config_management_t::mask }, 1045 { EGL_CONFORMANT, config_management_t::mask } 1046 }; 1047 1048 1049 static config_pair_t const config_defaults[] = { 1050 // attributes that are not specified are simply ignored, if a particular 1051 // one needs not be ignored, it must be specified here, eg: 1052 // { EGL_SURFACE_TYPE, EGL_WINDOW_BIT }, 1053 }; 1054 1055 // ---------------------------------------------------------------------------- 1056 1057 static status_t getConfigFormatInfo(EGLint configID, 1058 int32_t& pixelFormat, int32_t& depthFormat) 1059 { 1060 switch (configID) { 1061 case 0: 1062 pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 1063 depthFormat = 0; 1064 break; 1065 case 1: 1066 pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 1067 depthFormat = GGL_PIXEL_FORMAT_Z_16; 1068 break; 1069 case 2: 1070 pixelFormat = GGL_PIXEL_FORMAT_RGBX_8888; 1071 depthFormat = 0; 1072 break; 1073 case 3: 1074 pixelFormat = GGL_PIXEL_FORMAT_RGBX_8888; 1075 depthFormat = GGL_PIXEL_FORMAT_Z_16; 1076 break; 1077 case 4: 1078 pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 1079 depthFormat = 0; 1080 break; 1081 case 5: 1082 pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 1083 depthFormat = GGL_PIXEL_FORMAT_Z_16; 1084 break; 1085 case 6: 1086 pixelFormat = GGL_PIXEL_FORMAT_A_8; 1087 depthFormat = 0; 1088 break; 1089 case 7: 1090 pixelFormat = GGL_PIXEL_FORMAT_A_8; 1091 depthFormat = GGL_PIXEL_FORMAT_Z_16; 1092 break; 1093 default: 1094 return NAME_NOT_FOUND; 1095 } 1096 return NO_ERROR; 1097 } 1098 1099 // ---------------------------------------------------------------------------- 1100 1101 template<typename T> 1102 static int binarySearch(T const sortedArray[], int first, int last, EGLint key) 1103 { 1104 while (first <= last) { 1105 int mid = (first + last) / 2; 1106 if (key > sortedArray[mid].key) { 1107 first = mid + 1; 1108 } else if (key < sortedArray[mid].key) { 1109 last = mid - 1; 1110 } else { 1111 return mid; 1112 } 1113 } 1114 return -1; 1115 } 1116 1117 static int isAttributeMatching(int i, EGLint attr, EGLint val) 1118 { 1119 // look for the attribute in all of our configs 1120 config_pair_t const* configFound = gConfigs[i].array; 1121 int index = binarySearch<config_pair_t>( 1122 gConfigs[i].array, 1123 0, gConfigs[i].size-1, 1124 attr); 1125 if (index < 0) { 1126 configFound = config_base_attribute_list; 1127 index = binarySearch<config_pair_t>( 1128 config_base_attribute_list, 1129 0, NELEM(config_base_attribute_list)-1, 1130 attr); 1131 } 1132 if (index >= 0) { 1133 // attribute found, check if this config could match 1134 int cfgMgtIndex = binarySearch<config_management_t>( 1135 gConfigManagement, 1136 0, NELEM(gConfigManagement)-1, 1137 attr); 1138 if (cfgMgtIndex >= 0) { 1139 bool match = gConfigManagement[cfgMgtIndex].match( 1140 val, configFound[index].value); 1141 if (match) { 1142 // this config matches 1143 return 1; 1144 } 1145 } else { 1146 // attribute not found. this should NEVER happen. 1147 } 1148 } else { 1149 // error, this attribute doesn't exist 1150 } 1151 return 0; 1152 } 1153 1154 static int makeCurrent(ogles_context_t* gl) 1155 { 1156 ogles_context_t* current = (ogles_context_t*)getGlThreadSpecific(); 1157 if (gl) { 1158 egl_context_t* c = egl_context_t::context(gl); 1159 if (c->flags & egl_context_t::IS_CURRENT) { 1160 if (current != gl) { 1161 // it is an error to set a context current, if it's already 1162 // current to another thread 1163 return -1; 1164 } 1165 } else { 1166 if (current) { 1167 // mark the current context as not current, and flush 1168 //glFlush(); 1169 egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT; 1170 } 1171 } 1172 if (!(c->flags & egl_context_t::IS_CURRENT)) { 1173 // The context is not current, make it current! 1174 setGlThreadSpecific(gl); 1175 c->flags |= egl_context_t::IS_CURRENT; 1176 } 1177 } else { 1178 if (current) { 1179 // mark the current context as not current, and flush 1180 //glFlush(); 1181 egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT; 1182 } 1183 // this thread has no context attached to it 1184 setGlThreadSpecific(0); 1185 } 1186 return 0; 1187 } 1188 1189 static EGLBoolean getConfigAttrib(EGLDisplay dpy, EGLConfig config, 1190 EGLint attribute, EGLint *value) 1191 { 1192 size_t numConfigs = NELEM(gConfigs); 1193 int index = (int)config; 1194 if (uint32_t(index) >= numConfigs) 1195 return setError(EGL_BAD_CONFIG, EGL_FALSE); 1196 1197 int attrIndex; 1198 attrIndex = binarySearch<config_pair_t>( 1199 gConfigs[index].array, 1200 0, gConfigs[index].size-1, 1201 attribute); 1202 if (attrIndex>=0) { 1203 *value = gConfigs[index].array[attrIndex].value; 1204 return EGL_TRUE; 1205 } 1206 1207 attrIndex = binarySearch<config_pair_t>( 1208 config_base_attribute_list, 1209 0, NELEM(config_base_attribute_list)-1, 1210 attribute); 1211 if (attrIndex>=0) { 1212 *value = config_base_attribute_list[attrIndex].value; 1213 return EGL_TRUE; 1214 } 1215 return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1216 } 1217 1218 static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config, 1219 NativeWindowType window, const EGLint *attrib_list) 1220 { 1221 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1222 return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE); 1223 if (window == 0) 1224 return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); 1225 1226 EGLint surfaceType; 1227 if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) 1228 return EGL_FALSE; 1229 1230 if (!(surfaceType & EGL_WINDOW_BIT)) 1231 return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); 1232 1233 if (((ANativeWindow*)(window))->common.magic != 1234 ANDROID_NATIVE_WINDOW_MAGIC) { 1235 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 1236 } 1237 1238 EGLint configID; 1239 if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE) 1240 return EGL_FALSE; 1241 1242 int32_t depthFormat; 1243 int32_t pixelFormat; 1244 if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) { 1245 return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); 1246 } 1247 1248 // FIXME: we don't have access to the pixelFormat here just yet. 1249 // (it's possible that the surface is not fully initialized) 1250 // maybe this should be done after the page-flip 1251 //if (EGLint(info.format) != pixelFormat) 1252 // return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); 1253 1254 egl_surface_t* surface; 1255 surface = new egl_window_surface_v2_t(dpy, config, depthFormat, 1256 (ANativeWindow*)(window)); 1257 1258 if (!surface->initCheck()) { 1259 // there was a problem in the ctor, the error 1260 // flag has been set. 1261 delete surface; 1262 surface = 0; 1263 } 1264 return surface; 1265 } 1266 1267 static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, 1268 const EGLint *attrib_list) 1269 { 1270 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1271 return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE); 1272 1273 EGLint surfaceType; 1274 if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) 1275 return EGL_FALSE; 1276 1277 if (!(surfaceType & EGL_PBUFFER_BIT)) 1278 return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); 1279 1280 EGLint configID; 1281 if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE) 1282 return EGL_FALSE; 1283 1284 int32_t depthFormat; 1285 int32_t pixelFormat; 1286 if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) { 1287 return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); 1288 } 1289 1290 int32_t w = 0; 1291 int32_t h = 0; 1292 while (attrib_list[0]) { 1293 if (attrib_list[0] == EGL_WIDTH) w = attrib_list[1]; 1294 if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1]; 1295 attrib_list+=2; 1296 } 1297 1298 egl_surface_t* surface = 1299 new egl_pbuffer_surface_t(dpy, config, depthFormat, w, h, pixelFormat); 1300 1301 if (!surface->initCheck()) { 1302 // there was a problem in the ctor, the error 1303 // flag has been set. 1304 delete surface; 1305 surface = 0; 1306 } 1307 return surface; 1308 } 1309 1310 // ---------------------------------------------------------------------------- 1311 }; // namespace android 1312 // ---------------------------------------------------------------------------- 1313 1314 using namespace android; 1315 1316 // ---------------------------------------------------------------------------- 1317 // Initialization 1318 // ---------------------------------------------------------------------------- 1319 1320 EGLDisplay eglGetDisplay(NativeDisplayType display) 1321 { 1322 #ifndef HAVE_ANDROID_OS 1323 // this just needs to be done once 1324 if (gl::gGLKey == -1) { 1325 pthread_mutex_lock(&gInitMutex); 1326 if (gl::gGLKey == -1) 1327 pthread_key_create(&gl::gGLKey, NULL); 1328 pthread_mutex_unlock(&gInitMutex); 1329 } 1330 #endif 1331 if (display == EGL_DEFAULT_DISPLAY) { 1332 EGLDisplay dpy = (EGLDisplay)1; 1333 egl_display_t& d = egl_display_t::get_display(dpy); 1334 d.type = display; 1335 return dpy; 1336 } 1337 return EGL_NO_DISPLAY; 1338 } 1339 1340 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 1341 { 1342 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1343 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1344 1345 EGLBoolean res = EGL_TRUE; 1346 egl_display_t& d = egl_display_t::get_display(dpy); 1347 1348 if (android_atomic_inc(&d.initialized) == 0) { 1349 // initialize stuff here if needed 1350 //pthread_mutex_lock(&gInitMutex); 1351 //pthread_mutex_unlock(&gInitMutex); 1352 } 1353 1354 if (res == EGL_TRUE) { 1355 if (major != NULL) *major = VERSION_MAJOR; 1356 if (minor != NULL) *minor = VERSION_MINOR; 1357 } 1358 return res; 1359 } 1360 1361 EGLBoolean eglTerminate(EGLDisplay dpy) 1362 { 1363 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1364 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1365 1366 EGLBoolean res = EGL_TRUE; 1367 egl_display_t& d = egl_display_t::get_display(dpy); 1368 if (android_atomic_dec(&d.initialized) == 1) { 1369 // TODO: destroy all resources (surfaces, contexts, etc...) 1370 //pthread_mutex_lock(&gInitMutex); 1371 //pthread_mutex_unlock(&gInitMutex); 1372 } 1373 return res; 1374 } 1375 1376 // ---------------------------------------------------------------------------- 1377 // configuration 1378 // ---------------------------------------------------------------------------- 1379 1380 EGLBoolean eglGetConfigs( EGLDisplay dpy, 1381 EGLConfig *configs, 1382 EGLint config_size, EGLint *num_config) 1383 { 1384 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1385 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1386 1387 GLint numConfigs = NELEM(gConfigs); 1388 if (!configs) { 1389 *num_config = numConfigs; 1390 return EGL_TRUE; 1391 } 1392 GLint i; 1393 for (i=0 ; i<numConfigs && i<config_size ; i++) { 1394 *configs++ = (EGLConfig)i; 1395 } 1396 *num_config = i; 1397 return EGL_TRUE; 1398 } 1399 1400 EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, 1401 EGLConfig *configs, EGLint config_size, 1402 EGLint *num_config) 1403 { 1404 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1405 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1406 1407 if (ggl_unlikely(num_config==0)) { 1408 return setError(EGL_BAD_PARAMETER, EGL_FALSE); 1409 } 1410 1411 if (ggl_unlikely(attrib_list==0)) { 1412 /* 1413 * A NULL attrib_list should be treated as though it was an empty 1414 * one (terminated with EGL_NONE) as defined in 1415 * section 3.4.1 "Querying Configurations" in the EGL specification. 1416 */ 1417 static const EGLint dummy = EGL_NONE; 1418 attrib_list = &dummy; 1419 } 1420 1421 int numAttributes = 0; 1422 int numConfigs = NELEM(gConfigs); 1423 uint32_t possibleMatch = (1<<numConfigs)-1; 1424 while (possibleMatch && *attrib_list != EGL_NONE) { 1425 numAttributes++; 1426 EGLint attr = *attrib_list++; 1427 EGLint val = *attrib_list++; 1428 for (int i=0 ; possibleMatch && i<numConfigs ; i++) { 1429 if (!(possibleMatch & (1<<i))) 1430 continue; 1431 if (isAttributeMatching(i, attr, val) == 0) { 1432 possibleMatch &= ~(1<<i); 1433 } 1434 } 1435 } 1436 1437 // now, handle the attributes which have a useful default value 1438 for (size_t j=0 ; possibleMatch && j<NELEM(config_defaults) ; j++) { 1439 // see if this attribute was specified, if not, apply its 1440 // default value 1441 if (binarySearch<config_pair_t>( 1442 (config_pair_t const*)attrib_list, 1443 0, numAttributes-1, 1444 config_defaults[j].key) < 0) { 1445 for (int i=0 ; possibleMatch && i<numConfigs ; i++) { 1446 if (!(possibleMatch & (1<<i))) 1447 continue; 1448 if (isAttributeMatching(i, 1449 config_defaults[j].key, 1450 config_defaults[j].value) == 0) { 1451 possibleMatch &= ~(1<<i); 1452 } 1453 } 1454 } 1455 } 1456 1457 // return the configurations found 1458 int n=0; 1459 if (possibleMatch) { 1460 if (configs) { 1461 for (int i=0 ; config_size && i<numConfigs ; i++) { 1462 if (possibleMatch & (1<<i)) { 1463 *configs++ = (EGLConfig)i; 1464 config_size--; 1465 n++; 1466 } 1467 } 1468 } else { 1469 for (int i=0 ; i<numConfigs ; i++) { 1470 if (possibleMatch & (1<<i)) { 1471 n++; 1472 } 1473 } 1474 } 1475 } 1476 *num_config = n; 1477 return EGL_TRUE; 1478 } 1479 1480 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, 1481 EGLint attribute, EGLint *value) 1482 { 1483 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1484 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1485 1486 return getConfigAttrib(dpy, config, attribute, value); 1487 } 1488 1489 // ---------------------------------------------------------------------------- 1490 // surfaces 1491 // ---------------------------------------------------------------------------- 1492 1493 EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, 1494 NativeWindowType window, 1495 const EGLint *attrib_list) 1496 { 1497 return createWindowSurface(dpy, config, window, attrib_list); 1498 } 1499 1500 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface) 1501 { 1502 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1503 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1504 if (eglSurface != EGL_NO_SURFACE) { 1505 egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); 1506 if (!surface->isValid()) 1507 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1508 if (surface->dpy != dpy) 1509 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1510 if (surface->ctx) { 1511 // FIXME: this surface is current check what the spec says 1512 surface->disconnect(); 1513 surface->ctx = 0; 1514 } 1515 delete surface; 1516 } 1517 return EGL_TRUE; 1518 } 1519 1520 EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface eglSurface, 1521 EGLint attribute, EGLint *value) 1522 { 1523 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1524 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1525 egl_surface_t* surface = static_cast<egl_surface_t*>(eglSurface); 1526 if (!surface->isValid()) 1527 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1528 if (surface->dpy != dpy) 1529 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1530 1531 EGLBoolean ret = EGL_TRUE; 1532 switch (attribute) { 1533 case EGL_CONFIG_ID: 1534 ret = getConfigAttrib(dpy, surface->config, EGL_CONFIG_ID, value); 1535 break; 1536 case EGL_WIDTH: 1537 *value = surface->getWidth(); 1538 break; 1539 case EGL_HEIGHT: 1540 *value = surface->getHeight(); 1541 break; 1542 case EGL_LARGEST_PBUFFER: 1543 // not modified for a window or pixmap surface 1544 break; 1545 case EGL_TEXTURE_FORMAT: 1546 *value = EGL_NO_TEXTURE; 1547 break; 1548 case EGL_TEXTURE_TARGET: 1549 *value = EGL_NO_TEXTURE; 1550 break; 1551 case EGL_MIPMAP_TEXTURE: 1552 *value = EGL_FALSE; 1553 break; 1554 case EGL_MIPMAP_LEVEL: 1555 *value = 0; 1556 break; 1557 case EGL_RENDER_BUFFER: 1558 // TODO: return the real RENDER_BUFFER here 1559 *value = EGL_BACK_BUFFER; 1560 break; 1561 case EGL_HORIZONTAL_RESOLUTION: 1562 // pixel/mm * EGL_DISPLAY_SCALING 1563 *value = surface->getHorizontalResolution(); 1564 break; 1565 case EGL_VERTICAL_RESOLUTION: 1566 // pixel/mm * EGL_DISPLAY_SCALING 1567 *value = surface->getVerticalResolution(); 1568 break; 1569 case EGL_PIXEL_ASPECT_RATIO: { 1570 // w/h * EGL_DISPLAY_SCALING 1571 int wr = surface->getHorizontalResolution(); 1572 int hr = surface->getVerticalResolution(); 1573 *value = (wr * EGL_DISPLAY_SCALING) / hr; 1574 } 1575 break; 1576 case EGL_SWAP_BEHAVIOR: 1577 *value = surface->getSwapBehavior(); 1578 break; 1579 default: 1580 ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1581 } 1582 return ret; 1583 } 1584 1585 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, 1586 EGLContext share_list, const EGLint *attrib_list) 1587 { 1588 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1589 return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE); 1590 1591 ogles_context_t* gl = new (ogles_context_t); 1592 if (!gl) return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT); 1593 1594 gl->rasterizer.base = new egl_context_t; 1595 egl_context_t* c = static_cast<egl_context_t*>(gl->rasterizer.base); 1596 c->flags = egl_context_t::NEVER_CURRENT; 1597 c->dpy = dpy; 1598 c->config = config; 1599 c->read = 0; 1600 c->draw = 0; 1601 return (EGLContext)gl; 1602 } 1603 1604 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 1605 { 1606 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1607 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1608 egl_context_t* c = egl_context_t::context(ctx); 1609 if (c->flags & egl_context_t::IS_CURRENT) 1610 setGlThreadSpecific(0); 1611 delete ((ogles_context_t*)ctx); 1612 return EGL_TRUE; 1613 } 1614 1615 #define __LINE_STRING_0__(s) #s 1616 #define __LINE_STRING_1__(s) __LINE_STRING_0__(s) 1617 #define __LINE_STRING__ __LINE_STRING_1__(__LINE__) 1618 1619 EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, 1620 EGLSurface read, EGLContext ctx) 1621 { 1622 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1623 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1624 if (draw) { 1625 egl_surface_t* s = (egl_surface_t*)draw; 1626 if (!s->isValid()) 1627 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1628 if (s->dpy != dpy) 1629 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1630 // TODO: check that draw is compatible with the context 1631 } 1632 if (read && read!=draw) { 1633 egl_surface_t* s = (egl_surface_t*)read; 1634 if (!s->isValid()) 1635 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1636 if (s->dpy != dpy) 1637 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1638 // TODO: check that read is compatible with the context 1639 } 1640 1641 EGLContext current_ctx = EGL_NO_CONTEXT; 1642 1643 if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT)) 1644 return setError(EGL_BAD_MATCH, EGL_FALSE); 1645 1646 if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT)) 1647 return setError(EGL_BAD_MATCH, EGL_FALSE); 1648 1649 if (ctx == EGL_NO_CONTEXT) { 1650 // if we're detaching, we need the current context 1651 current_ctx = (EGLContext)getGlThreadSpecific(); 1652 } else { 1653 egl_context_t* c = egl_context_t::context(ctx); 1654 egl_surface_t* d = (egl_surface_t*)draw; 1655 egl_surface_t* r = (egl_surface_t*)read; 1656 if ((d && d->ctx && d->ctx != ctx) || 1657 (r && r->ctx && r->ctx != ctx)) { 1658 // one of the surface is bound to a context in another thread 1659 return setError(EGL_BAD_ACCESS, EGL_FALSE); 1660 } 1661 } 1662 1663 puts("eglMakeCurrent:"__LINE_STRING__); 1664 ogles_context_t* gl = (ogles_context_t*)ctx; 1665 if (makeCurrent(gl) == 0) { 1666 if (ctx) { 1667 egl_context_t* c = egl_context_t::context(ctx); 1668 egl_surface_t* d = (egl_surface_t*)draw; 1669 egl_surface_t* r = (egl_surface_t*)read; 1670 1671 if (c->draw) { 1672 egl_surface_t* s = reinterpret_cast<egl_surface_t*>(c->draw); 1673 s->disconnect(); 1674 } 1675 1676 c->draw = draw; 1677 c->read = read; 1678 puts("eglMakeCurrent:"__LINE_STRING__); 1679 if (d) { 1680 if (d->connect() == EGL_FALSE) { 1681 return EGL_FALSE; 1682 } 1683 d->ctx = ctx; 1684 d->bindDrawSurface(gl); 1685 } 1686 if (r) { 1687 // FIXME: lock/connect the read surface too 1688 r->ctx = ctx; 1689 //r->bindReadSurface(gl); 1690 } 1691 } else { 1692 puts("eglMakeCurrent:"__LINE_STRING__); 1693 // if surfaces were bound to the context bound to this thread 1694 // mark then as unbound. 1695 if (current_ctx) { 1696 egl_context_t* c = egl_context_t::context(current_ctx); 1697 egl_surface_t* d = (egl_surface_t*)c->draw; 1698 egl_surface_t* r = (egl_surface_t*)c->read; 1699 if (d) { 1700 c->draw = 0; 1701 d->ctx = EGL_NO_CONTEXT; 1702 d->disconnect(); 1703 } 1704 if (r) { 1705 c->read = 0; 1706 r->ctx = EGL_NO_CONTEXT; 1707 // FIXME: unlock/disconnect the read surface too 1708 } 1709 } 1710 } 1711 return EGL_TRUE; 1712 } 1713 return setError(EGL_BAD_ACCESS, EGL_FALSE); 1714 } 1715 1716 EGLContext eglGetCurrentContext(void) 1717 { 1718 // eglGetCurrentContext returns the current EGL rendering context, 1719 // as specified by eglMakeCurrent. If no context is current, 1720 // EGL_NO_CONTEXT is returned. 1721 return (EGLContext)getGlThreadSpecific(); 1722 } 1723 1724 EGLSurface eglGetCurrentSurface(EGLint readdraw) 1725 { 1726 // eglGetCurrentSurface returns the read or draw surface attached 1727 // to the current EGL rendering context, as specified by eglMakeCurrent. 1728 // If no context is current, EGL_NO_SURFACE is returned. 1729 EGLContext ctx = (EGLContext)getGlThreadSpecific(); 1730 if (ctx == EGL_NO_CONTEXT) return EGL_NO_SURFACE; 1731 egl_context_t* c = egl_context_t::context(ctx); 1732 if (readdraw == EGL_READ) { 1733 return c->read; 1734 } else if (readdraw == EGL_DRAW) { 1735 return c->draw; 1736 } 1737 return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); 1738 } 1739 1740 EGLDisplay eglGetCurrentDisplay(void) 1741 { 1742 // eglGetCurrentDisplay returns the current EGL display connection 1743 // for the current EGL rendering context, as specified by eglMakeCurrent. 1744 // If no context is current, EGL_NO_DISPLAY is returned. 1745 EGLContext ctx = (EGLContext)getGlThreadSpecific(); 1746 if (ctx == EGL_NO_CONTEXT) return EGL_NO_DISPLAY; 1747 egl_context_t* c = egl_context_t::context(ctx); 1748 return c->dpy; 1749 } 1750 1751 EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx, 1752 EGLint attribute, EGLint *value) 1753 { 1754 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1755 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1756 egl_context_t* c = egl_context_t::context(ctx); 1757 switch (attribute) { 1758 case EGL_CONFIG_ID: 1759 // Returns the ID of the EGL frame buffer configuration with 1760 // respect to which the context was created 1761 return getConfigAttrib(dpy, c->config, EGL_CONFIG_ID, value); 1762 } 1763 return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1764 } 1765 1766 EGLBoolean eglWaitNative(EGLint engine) 1767 { 1768 return EGL_TRUE; 1769 } 1770 1771 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) 1772 { 1773 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1774 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1775 1776 egl_surface_t* d = static_cast<egl_surface_t*>(draw); 1777 if (!d->isValid()) 1778 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1779 if (d->dpy != dpy) 1780 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1781 1782 // post the surface 1783 d->swapBuffers(); 1784 1785 // if it's bound to a context, update the buffer 1786 if (d->ctx != EGL_NO_CONTEXT) { 1787 d->bindDrawSurface((ogles_context_t*)d->ctx); 1788 // if this surface is also the read surface of the context 1789 // it is bound to, make sure to update the read buffer as well. 1790 // The EGL spec is a little unclear about this. 1791 egl_context_t* c = egl_context_t::context(d->ctx); 1792 if (c->read == draw) { 1793 //d->bindReadSurface((ogles_context_t*)d->ctx); 1794 } 1795 } 1796 1797 return EGL_TRUE; 1798 } 1799 1800 EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface, 1801 NativePixmapType target) 1802 { 1803 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1804 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1805 // TODO: eglCopyBuffers() 1806 return EGL_FALSE; 1807 } 1808 1809 EGLint eglGetError(void) 1810 { 1811 return getError(); 1812 } 1813 1814 const char* eglQueryString(EGLDisplay dpy, EGLint name) 1815 { 1816 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1817 return setError(EGL_BAD_DISPLAY, (const char*)0); 1818 1819 switch (name) { 1820 case EGL_VENDOR: 1821 return gVendorString; 1822 case EGL_VERSION: 1823 return gVersionString; 1824 case EGL_EXTENSIONS: 1825 return gExtensionsString; 1826 case EGL_CLIENT_APIS: 1827 return gClientApiString; 1828 } 1829 return setError(EGL_BAD_PARAMETER, (const char *)0); 1830 } 1831 1832 // ---------------------------------------------------------------------------- 1833 // ANDROID extensions 1834 // ---------------------------------------------------------------------------- 1835 1836 EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, 1837 EGLint left, EGLint top, EGLint width, EGLint height) 1838 { 1839 if (egl_display_t::is_valid(dpy) == EGL_FALSE) 1840 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1841 1842 egl_surface_t* d = static_cast<egl_surface_t*>(draw); 1843 if (!d->isValid()) 1844 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1845 if (d->dpy != dpy) 1846 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1847 1848 // post the surface 1849 d->setSwapRectangle(left, top, width, height); 1850 1851 return EGL_TRUE; 1852 } 1853 1854 static struct S 1855 { 1856 sp<SurfaceComposerClient> client; 1857 sp<SurfaceControl> surfaceControl; 1858 sp<Surface> surface; 1859 ~S() 1860 { 1861 client->dispose(); 1862 } 1863 } * s = NULL; 1864 static ANativeWindow * window; 1865 static EGLDisplay display; 1866 static EGLContext eglCtx; 1867 static EGLSurface drawSurface; 1868 1869 extern "C" int SetupDrawingSurface(unsigned * width, unsigned * height, unsigned * bpp) 1870 { 1871 s = new S; 1872 // create a client to surfaceflinger 1873 s->client = new SurfaceComposerClient(); 1874 1875 s->surfaceControl = s->client->createSurface(getpid(), 0, 640, 400, PIXEL_FORMAT_RGBA_8888); 1876 SurfaceComposerClient::openGlobalTransaction(); 1877 s->surfaceControl->setLayer(25000); 1878 s->surfaceControl->show(); 1879 SurfaceComposerClient::closeGlobalTransaction(); 1880 1881 s->surface = s->surfaceControl->getSurface(); 1882 window = s->surface.get(); 1883 1884 printf("window=%p\n", window); 1885 assert(window); 1886 display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 1887 1888 EGLint attrib_list[] = { 1889 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 1890 EGL_BUFFER_SIZE, 32, 1891 EGL_RED_SIZE, 8, 1892 EGL_GREEN_SIZE, 8, 1893 EGL_BLUE_SIZE, 8, 1894 EGL_NONE 1895 }; 1896 1897 EGLConfig configs[12] = {0}; 1898 int num_config = -1; 1899 eglChooseConfig(display, attrib_list, configs, sizeof(configs) / sizeof(*configs), &num_config); 1900 printf("eglChooseConfig %d \n", num_config); 1901 1902 eglCtx = eglCreateContext(display, configs[0], NULL, NULL); 1903 printf("eglCtx=%p \n", eglCtx); 1904 android::global_ctx = (android::ogles_context_t *)eglCtx; 1905 1906 drawSurface = eglCreateWindowSurface(display, configs[0], window, NULL); 1907 printf("drawSurface=%p \n", drawSurface); 1908 1909 EGLBoolean ret = eglMakeCurrent(display, drawSurface, drawSurface, eglCtx); 1910 printf("eglMakeCurrent=%d \n", ret); 1911 assert(EGL_TRUE == ret); 1912 1913 ret = eglSwapBuffers(display, drawSurface); 1914 printf("eglSwapBuffers=%d \n", ret); 1915 assert(EGL_TRUE == ret); 1916 1917 ogles_context_t * gl = (ogles_context_t *)eglCtx; 1918 *width = gl->width; 1919 *height = gl->height; 1920 assert(PIXEL_FORMAT_RGBA_8888 == gl->format); 1921 *bpp = 32; 1922 1923 puts("end SetupDrawingSurface"); 1924 return 0; 1925 } 1926 1927 extern "C" void * PresentDrawingSurface() 1928 { 1929 EGLBoolean ret = eglSwapBuffers(display, drawSurface); 1930 //printf("eglSwapBuffers=%d \n", ret); 1931 assert(EGL_TRUE == ret); 1932 1933 ogles_context_t * gl = (ogles_context_t *)eglCtx; 1934 assert(gl->width == gl->stride); 1935 assert(PIXEL_FORMAT_RGBA_8888 == gl->format); 1936 return gl->bits; 1937 } 1938 1939 extern "C" void DisposeDrawingSurface() 1940 { 1941 eglDestroySurface(display, drawSurface); 1942 eglDestroyContext(display, eglCtx); 1943 delete s; 1944 s = NULL; 1945 puts("DisposeDrawingSurface"); 1946 } 1947 1948 #endif // #ifdef __arm__ 1949