1 /* 2 * Copyright (C) 2007 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 #include <stdlib.h> 18 #include <stdint.h> 19 #include <sys/types.h> 20 21 #include <utils/Errors.h> 22 #include <utils/Log.h> 23 #include <binder/IPCThreadState.h> 24 #include <binder/IServiceManager.h> 25 26 #include <GLES/gl.h> 27 #include <GLES/glext.h> 28 29 #include <hardware/hardware.h> 30 31 #include "clz.h" 32 #include "LayerBase.h" 33 #include "SurfaceFlinger.h" 34 #include "DisplayHardware/DisplayHardware.h" 35 36 37 namespace android { 38 39 // --------------------------------------------------------------------------- 40 41 const uint32_t LayerBase::typeInfo = 1; 42 const char* const LayerBase::typeID = "LayerBase"; 43 44 const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2; 45 const char* const LayerBaseClient::typeID = "LayerBaseClient"; 46 47 // --------------------------------------------------------------------------- 48 49 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) 50 : dpy(display), contentDirty(false), 51 mFlinger(flinger), 52 mTransformed(false), 53 mUseLinearFiltering(false), 54 mOrientation(0), 55 mLeft(0), mTop(0), 56 mTransactionFlags(0), 57 mPremultipliedAlpha(true), mDebug(false), 58 mInvalidate(0) 59 { 60 const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); 61 mFlags = hw.getFlags(); 62 } 63 64 LayerBase::~LayerBase() 65 { 66 } 67 68 void LayerBase::setName(const String8& name) { 69 mName = name; 70 } 71 72 String8 LayerBase::getName() const { 73 return mName; 74 } 75 76 const GraphicPlane& LayerBase::graphicPlane(int dpy) const 77 { 78 return mFlinger->graphicPlane(dpy); 79 } 80 81 GraphicPlane& LayerBase::graphicPlane(int dpy) 82 { 83 return mFlinger->graphicPlane(dpy); 84 } 85 86 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) 87 { 88 uint32_t layerFlags = 0; 89 if (flags & ISurfaceComposer::eHidden) 90 layerFlags = ISurfaceComposer::eLayerHidden; 91 92 if (flags & ISurfaceComposer::eNonPremultiplied) 93 mPremultipliedAlpha = false; 94 95 mCurrentState.z = 0; 96 mCurrentState.w = w; 97 mCurrentState.h = h; 98 mCurrentState.requested_w = w; 99 mCurrentState.requested_h = h; 100 mCurrentState.alpha = 0xFF; 101 mCurrentState.flags = layerFlags; 102 mCurrentState.sequence = 0; 103 mCurrentState.transform.set(0, 0); 104 105 // drawing state & current state are identical 106 mDrawingState = mCurrentState; 107 } 108 109 void LayerBase::commitTransaction() { 110 mDrawingState = mCurrentState; 111 } 112 void LayerBase::forceVisibilityTransaction() { 113 // this can be called without SurfaceFlinger.mStateLock, but if we 114 // can atomically increment the sequence number, it doesn't matter. 115 android_atomic_inc(&mCurrentState.sequence); 116 requestTransaction(); 117 } 118 bool LayerBase::requestTransaction() { 119 int32_t old = setTransactionFlags(eTransactionNeeded); 120 return ((old & eTransactionNeeded) == 0); 121 } 122 uint32_t LayerBase::getTransactionFlags(uint32_t flags) { 123 return android_atomic_and(~flags, &mTransactionFlags) & flags; 124 } 125 uint32_t LayerBase::setTransactionFlags(uint32_t flags) { 126 return android_atomic_or(flags, &mTransactionFlags); 127 } 128 129 bool LayerBase::setPosition(int32_t x, int32_t y) { 130 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 131 return false; 132 mCurrentState.sequence++; 133 mCurrentState.transform.set(x, y); 134 requestTransaction(); 135 return true; 136 } 137 bool LayerBase::setLayer(uint32_t z) { 138 if (mCurrentState.z == z) 139 return false; 140 mCurrentState.sequence++; 141 mCurrentState.z = z; 142 requestTransaction(); 143 return true; 144 } 145 bool LayerBase::setSize(uint32_t w, uint32_t h) { 146 if (mCurrentState.requested_w == w && mCurrentState.requested_h == h) 147 return false; 148 mCurrentState.requested_w = w; 149 mCurrentState.requested_h = h; 150 requestTransaction(); 151 return true; 152 } 153 bool LayerBase::setAlpha(uint8_t alpha) { 154 if (mCurrentState.alpha == alpha) 155 return false; 156 mCurrentState.sequence++; 157 mCurrentState.alpha = alpha; 158 requestTransaction(); 159 return true; 160 } 161 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) { 162 // TODO: check the matrix has changed 163 mCurrentState.sequence++; 164 mCurrentState.transform.set( 165 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 166 requestTransaction(); 167 return true; 168 } 169 bool LayerBase::setTransparentRegionHint(const Region& transparent) { 170 // TODO: check the region has changed 171 mCurrentState.sequence++; 172 mCurrentState.transparentRegion = transparent; 173 requestTransaction(); 174 return true; 175 } 176 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) { 177 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 178 if (mCurrentState.flags == newFlags) 179 return false; 180 mCurrentState.sequence++; 181 mCurrentState.flags = newFlags; 182 requestTransaction(); 183 return true; 184 } 185 186 Rect LayerBase::visibleBounds() const 187 { 188 return mTransformedBounds; 189 } 190 191 void LayerBase::setVisibleRegion(const Region& visibleRegion) { 192 // always called from main thread 193 visibleRegionScreen = visibleRegion; 194 } 195 196 void LayerBase::setCoveredRegion(const Region& coveredRegion) { 197 // always called from main thread 198 coveredRegionScreen = coveredRegion; 199 } 200 201 uint32_t LayerBase::doTransaction(uint32_t flags) 202 { 203 const Layer::State& front(drawingState()); 204 const Layer::State& temp(currentState()); 205 206 if ((front.requested_w != temp.requested_w) || 207 (front.requested_h != temp.requested_h)) { 208 // resize the layer, set the physical size to the requested size 209 Layer::State& editTemp(currentState()); 210 editTemp.w = temp.requested_w; 211 editTemp.h = temp.requested_h; 212 } 213 214 if ((front.w != temp.w) || (front.h != temp.h)) { 215 // invalidate and recompute the visible regions if needed 216 flags |= Layer::eVisibleRegion; 217 } 218 219 if (temp.sequence != front.sequence) { 220 // invalidate and recompute the visible regions if needed 221 flags |= eVisibleRegion; 222 this->contentDirty = true; 223 224 const bool linearFiltering = mUseLinearFiltering; 225 mUseLinearFiltering = false; 226 if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 227 // we may use linear filtering, if the matrix scales us 228 const uint8_t type = temp.transform.getType(); 229 if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) { 230 mUseLinearFiltering = true; 231 } 232 } 233 } 234 235 // Commit the transaction 236 commitTransaction(); 237 return flags; 238 } 239 240 void LayerBase::validateVisibility(const Transform& planeTransform) 241 { 242 const Layer::State& s(drawingState()); 243 const Transform tr(planeTransform * s.transform); 244 const bool transformed = tr.transformed(); 245 246 uint32_t w = s.w; 247 uint32_t h = s.h; 248 tr.transform(mVertices[0], 0, 0); 249 tr.transform(mVertices[1], 0, h); 250 tr.transform(mVertices[2], w, h); 251 tr.transform(mVertices[3], w, 0); 252 if (UNLIKELY(transformed)) { 253 // NOTE: here we could also punt if we have too many rectangles 254 // in the transparent region 255 if (tr.preserveRects()) { 256 // transform the transparent region 257 transparentRegionScreen = tr.transform(s.transparentRegion); 258 } else { 259 // transformation too complex, can't do the transparent region 260 // optimization. 261 transparentRegionScreen.clear(); 262 } 263 } else { 264 transparentRegionScreen = s.transparentRegion; 265 } 266 267 // cache a few things... 268 mOrientation = tr.getOrientation(); 269 mTransformedBounds = tr.makeBounds(w, h); 270 mTransformed = transformed; 271 mLeft = tr.tx(); 272 mTop = tr.ty(); 273 } 274 275 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 276 { 277 } 278 279 void LayerBase::unlockPageFlip( 280 const Transform& planeTransform, Region& outDirtyRegion) 281 { 282 if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { 283 outDirtyRegion.orSelf(visibleRegionScreen); 284 } 285 } 286 287 void LayerBase::finishPageFlip() 288 { 289 } 290 291 void LayerBase::invalidate() 292 { 293 if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 294 mFlinger->signalEvent(); 295 } 296 } 297 298 void LayerBase::drawRegion(const Region& reg) const 299 { 300 Region::const_iterator it = reg.begin(); 301 Region::const_iterator const end = reg.end(); 302 if (it != end) { 303 Rect r; 304 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 305 const int32_t fbWidth = hw.getWidth(); 306 const int32_t fbHeight = hw.getHeight(); 307 const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 308 { fbWidth, fbHeight }, { 0, fbHeight } }; 309 glVertexPointer(2, GL_SHORT, 0, vertices); 310 while (it != end) { 311 const Rect& r = *it++; 312 const GLint sy = fbHeight - (r.top + r.height()); 313 glScissor(r.left, sy, r.width(), r.height()); 314 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 315 } 316 } 317 } 318 319 void LayerBase::draw(const Region& inClip) const 320 { 321 // invalidate the region we'll update 322 Region clip(inClip); // copy-on-write, so no-op most of the time 323 324 // Remove the transparent area from the clipping region 325 const State& s = drawingState(); 326 if (LIKELY(!s.transparentRegion.isEmpty())) { 327 clip.subtract(transparentRegionScreen); 328 if (clip.isEmpty()) { 329 // usually this won't happen because this should be taken care of 330 // by SurfaceFlinger::computeVisibleRegions() 331 return; 332 } 333 } 334 335 // reset GL state 336 glEnable(GL_SCISSOR_TEST); 337 338 onDraw(clip); 339 340 /* 341 glDisable(GL_TEXTURE_2D); 342 glDisable(GL_DITHER); 343 glEnable(GL_BLEND); 344 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 345 glColor4x(0, 0x8000, 0, 0x10000); 346 drawRegion(transparentRegionScreen); 347 glDisable(GL_BLEND); 348 */ 349 } 350 351 GLuint LayerBase::createTexture() const 352 { 353 GLuint textureName = -1; 354 glGenTextures(1, &textureName); 355 glBindTexture(GL_TEXTURE_2D, textureName); 356 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 357 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 358 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 359 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 360 return textureName; 361 } 362 363 void LayerBase::clearWithOpenGL(const Region& clip, GLclampx red, 364 GLclampx green, GLclampx blue, 365 GLclampx alpha) const 366 { 367 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 368 const uint32_t fbHeight = hw.getHeight(); 369 glColor4x(red,green,blue,alpha); 370 glDisable(GL_TEXTURE_2D); 371 glDisable(GL_BLEND); 372 glDisable(GL_DITHER); 373 374 Region::const_iterator it = clip.begin(); 375 Region::const_iterator const end = clip.end(); 376 glEnable(GL_SCISSOR_TEST); 377 glVertexPointer(2, GL_FIXED, 0, mVertices); 378 while (it != end) { 379 const Rect& r = *it++; 380 const GLint sy = fbHeight - (r.top + r.height()); 381 glScissor(r.left, sy, r.width(), r.height()); 382 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 383 } 384 } 385 386 void LayerBase::clearWithOpenGL(const Region& clip) const 387 { 388 clearWithOpenGL(clip,0,0,0,0); 389 } 390 391 void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const 392 { 393 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 394 const uint32_t fbHeight = hw.getHeight(); 395 const State& s(drawingState()); 396 397 // bind our texture 398 validateTexture(texture.name); 399 uint32_t width = texture.width; 400 uint32_t height = texture.height; 401 402 glEnable(GL_TEXTURE_2D); 403 404 if (UNLIKELY(s.alpha < 0xFF)) { 405 // We have an alpha-modulation. We need to modulate all 406 // texture components by alpha because we're always using 407 // premultiplied alpha. 408 409 // If the texture doesn't have an alpha channel we can 410 // use REPLACE and switch to non premultiplied alpha 411 // blending (SRCA/ONE_MINUS_SRCA). 412 413 GLenum env, src; 414 if (needsBlending()) { 415 env = GL_MODULATE; 416 src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 417 } else { 418 env = GL_REPLACE; 419 src = GL_SRC_ALPHA; 420 } 421 const GGLfixed alpha = (s.alpha << 16)/255; 422 glColor4x(alpha, alpha, alpha, alpha); 423 glEnable(GL_BLEND); 424 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 425 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); 426 } else { 427 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 428 glColor4x(0x10000, 0x10000, 0x10000, 0x10000); 429 if (needsBlending()) { 430 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 431 glEnable(GL_BLEND); 432 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 433 } else { 434 glDisable(GL_BLEND); 435 } 436 } 437 438 Region::const_iterator it = clip.begin(); 439 Region::const_iterator const end = clip.end(); 440 441 //StopWatch watch("GL transformed"); 442 const GLfixed texCoords[4][2] = { 443 { 0, 0 }, 444 { 0, 0x10000 }, 445 { 0x10000, 0x10000 }, 446 { 0x10000, 0 } 447 }; 448 449 glMatrixMode(GL_TEXTURE); 450 glLoadIdentity(); 451 452 // the texture's source is rotated 453 switch (texture.transform) { 454 case HAL_TRANSFORM_ROT_90: 455 glTranslatef(0, 1, 0); 456 glRotatef(-90, 0, 0, 1); 457 break; 458 case HAL_TRANSFORM_ROT_180: 459 glTranslatef(1, 1, 0); 460 glRotatef(-180, 0, 0, 1); 461 break; 462 case HAL_TRANSFORM_ROT_270: 463 glTranslatef(1, 0, 0); 464 glRotatef(-270, 0, 0, 1); 465 break; 466 } 467 468 if (texture.NPOTAdjust) { 469 glScalef(texture.wScale, texture.hScale, 1.0f); 470 } 471 472 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 473 glVertexPointer(2, GL_FIXED, 0, mVertices); 474 glTexCoordPointer(2, GL_FIXED, 0, texCoords); 475 476 while (it != end) { 477 const Rect& r = *it++; 478 const GLint sy = fbHeight - (r.top + r.height()); 479 glScissor(r.left, sy, r.width(), r.height()); 480 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 481 } 482 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 483 } 484 485 void LayerBase::validateTexture(GLint textureName) const 486 { 487 glBindTexture(GL_TEXTURE_2D, textureName); 488 // TODO: reload the texture if needed 489 // this is currently done in loadTexture() below 490 if (mUseLinearFiltering) { 491 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 492 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 493 } else { 494 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 495 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 496 } 497 498 if (needsDithering()) { 499 glEnable(GL_DITHER); 500 } else { 501 glDisable(GL_DITHER); 502 } 503 } 504 505 bool LayerBase::isSupportedYuvFormat(int format) const 506 { 507 switch (format) { 508 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 509 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 510 case HAL_PIXEL_FORMAT_YCbCr_422_P: 511 case HAL_PIXEL_FORMAT_YCbCr_420_P: 512 case HAL_PIXEL_FORMAT_YCbCr_422_I: 513 case HAL_PIXEL_FORMAT_YCbCr_420_I: 514 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 515 return true; 516 } 517 return false; 518 } 519 520 void LayerBase::loadTexture(Texture* texture, 521 const Region& dirty, const GGLSurface& t) const 522 { 523 if (texture->name == -1U) { 524 // uh? 525 return; 526 } 527 528 glBindTexture(GL_TEXTURE_2D, texture->name); 529 530 /* 531 * In OpenGL ES we can't specify a stride with glTexImage2D (however, 532 * GL_UNPACK_ALIGNMENT is a limited form of stride). 533 * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we 534 * need to do something reasonable (here creating a bigger texture). 535 * 536 * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT); 537 * 538 * This situation doesn't happen often, but some h/w have a limitation 539 * for their framebuffer (eg: must be multiple of 8 pixels), and 540 * we need to take that into account when using these buffers as 541 * textures. 542 * 543 * This should never be a problem with POT textures 544 */ 545 546 int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format)); 547 unpack = 1 << ((unpack > 3) ? 3 : unpack); 548 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); 549 550 /* 551 * round to POT if needed 552 */ 553 if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { 554 texture->NPOTAdjust = true; 555 } 556 557 if (texture->NPOTAdjust) { 558 // find the smallest power-of-two that will accommodate our surface 559 texture->potWidth = 1 << (31 - clz(t.width)); 560 texture->potHeight = 1 << (31 - clz(t.height)); 561 if (texture->potWidth < t.width) texture->potWidth <<= 1; 562 if (texture->potHeight < t.height) texture->potHeight <<= 1; 563 texture->wScale = float(t.width) / texture->potWidth; 564 texture->hScale = float(t.height) / texture->potHeight; 565 } else { 566 texture->potWidth = t.width; 567 texture->potHeight = t.height; 568 } 569 570 Rect bounds(dirty.bounds()); 571 GLvoid* data = 0; 572 if (texture->width != t.width || texture->height != t.height) { 573 texture->width = t.width; 574 texture->height = t.height; 575 576 // texture size changed, we need to create a new one 577 bounds.set(Rect(t.width, t.height)); 578 if (t.width == texture->potWidth && 579 t.height == texture->potHeight) { 580 // we can do it one pass 581 data = t.data; 582 } 583 584 if (t.format == HAL_PIXEL_FORMAT_RGB_565) { 585 glTexImage2D(GL_TEXTURE_2D, 0, 586 GL_RGB, texture->potWidth, texture->potHeight, 0, 587 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); 588 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { 589 glTexImage2D(GL_TEXTURE_2D, 0, 590 GL_RGBA, texture->potWidth, texture->potHeight, 0, 591 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); 592 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || 593 t.format == HAL_PIXEL_FORMAT_RGBX_8888) { 594 glTexImage2D(GL_TEXTURE_2D, 0, 595 GL_RGBA, texture->potWidth, texture->potHeight, 0, 596 GL_RGBA, GL_UNSIGNED_BYTE, data); 597 } else if (isSupportedYuvFormat(t.format)) { 598 // just show the Y plane of YUV buffers 599 glTexImage2D(GL_TEXTURE_2D, 0, 600 GL_LUMINANCE, texture->potWidth, texture->potHeight, 0, 601 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 602 } else { 603 // oops, we don't handle this format! 604 LOGE("layer %p, texture=%d, using format %d, which is not " 605 "supported by the GL", this, texture->name, t.format); 606 } 607 } 608 if (!data) { 609 if (t.format == HAL_PIXEL_FORMAT_RGB_565) { 610 glTexSubImage2D(GL_TEXTURE_2D, 0, 611 0, bounds.top, t.width, bounds.height(), 612 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 613 t.data + bounds.top*t.stride*2); 614 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { 615 glTexSubImage2D(GL_TEXTURE_2D, 0, 616 0, bounds.top, t.width, bounds.height(), 617 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 618 t.data + bounds.top*t.stride*2); 619 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || 620 t.format == HAL_PIXEL_FORMAT_RGBX_8888) { 621 glTexSubImage2D(GL_TEXTURE_2D, 0, 622 0, bounds.top, t.width, bounds.height(), 623 GL_RGBA, GL_UNSIGNED_BYTE, 624 t.data + bounds.top*t.stride*4); 625 } else if (isSupportedYuvFormat(t.format)) { 626 // just show the Y plane of YUV buffers 627 glTexSubImage2D(GL_TEXTURE_2D, 0, 628 0, bounds.top, t.width, bounds.height(), 629 GL_LUMINANCE, GL_UNSIGNED_BYTE, 630 t.data + bounds.top*t.stride); 631 } 632 } 633 } 634 635 status_t LayerBase::initializeEglImage( 636 const sp<GraphicBuffer>& buffer, Texture* texture) 637 { 638 status_t err = NO_ERROR; 639 640 // we need to recreate the texture 641 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 642 643 // free the previous image 644 if (texture->image != EGL_NO_IMAGE_KHR) { 645 eglDestroyImageKHR(dpy, texture->image); 646 texture->image = EGL_NO_IMAGE_KHR; 647 } 648 649 // construct an EGL_NATIVE_BUFFER_ANDROID 650 android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); 651 652 // create the new EGLImageKHR 653 const EGLint attrs[] = { 654 EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 655 EGL_NONE, EGL_NONE 656 }; 657 texture->image = eglCreateImageKHR( 658 dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, 659 (EGLClientBuffer)clientBuf, attrs); 660 661 if (texture->image != EGL_NO_IMAGE_KHR) { 662 glBindTexture(GL_TEXTURE_2D, texture->name); 663 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 664 (GLeglImageOES)texture->image); 665 GLint error = glGetError(); 666 if (UNLIKELY(error != GL_NO_ERROR)) { 667 LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) " 668 "failed err=0x%04x", 669 this, texture->image, error); 670 err = INVALID_OPERATION; 671 } else { 672 // Everything went okay! 673 texture->NPOTAdjust = false; 674 texture->dirty = false; 675 texture->width = clientBuf->width; 676 texture->height = clientBuf->height; 677 } 678 } else { 679 LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x", 680 this, eglGetError()); 681 err = INVALID_OPERATION; 682 } 683 return err; 684 } 685 686 687 // --------------------------------------------------------------------------- 688 689 int32_t LayerBaseClient::sIdentity = 0; 690 691 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 692 const sp<Client>& client, int32_t i) 693 : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i), 694 mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 695 { 696 lcblk = new SharedBufferServer( 697 client->ctrlblk, i, NUM_BUFFERS, 698 mIdentity); 699 } 700 701 void LayerBaseClient::onFirstRef() 702 { 703 sp<Client> client(this->client.promote()); 704 if (client != 0) { 705 client->bindLayer(this, mIndex); 706 } 707 } 708 709 LayerBaseClient::~LayerBaseClient() 710 { 711 sp<Client> client(this->client.promote()); 712 if (client != 0) { 713 client->free(mIndex); 714 } 715 delete lcblk; 716 } 717 718 int32_t LayerBaseClient::serverIndex() const 719 { 720 sp<Client> client(this->client.promote()); 721 if (client != 0) { 722 return (client->cid<<16)|mIndex; 723 } 724 return 0xFFFF0000 | mIndex; 725 } 726 727 sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() 728 { 729 sp<Surface> s; 730 Mutex::Autolock _l(mLock); 731 s = mClientSurface.promote(); 732 if (s == 0) { 733 s = createSurface(); 734 mClientSurface = s; 735 } 736 return s; 737 } 738 739 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const 740 { 741 return new Surface(mFlinger, clientIndex(), mIdentity, 742 const_cast<LayerBaseClient *>(this)); 743 } 744 745 // called with SurfaceFlinger::mStateLock as soon as the layer is entered 746 // in the purgatory list 747 void LayerBaseClient::onRemoved() 748 { 749 // wake up the condition 750 lcblk->setStatus(NO_INIT); 751 } 752 753 // --------------------------------------------------------------------------- 754 755 LayerBaseClient::Surface::Surface( 756 const sp<SurfaceFlinger>& flinger, 757 SurfaceID id, int identity, 758 const sp<LayerBaseClient>& owner) 759 : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner) 760 { 761 } 762 763 LayerBaseClient::Surface::~Surface() 764 { 765 /* 766 * This is a good place to clean-up all client resources 767 */ 768 769 // destroy client resources 770 sp<LayerBaseClient> layer = getOwner(); 771 if (layer != 0) { 772 mFlinger->destroySurface(layer); 773 } 774 } 775 776 sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const { 777 sp<LayerBaseClient> owner(mOwner.promote()); 778 return owner; 779 } 780 781 status_t LayerBaseClient::Surface::onTransact( 782 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 783 { 784 switch (code) { 785 case REGISTER_BUFFERS: 786 case UNREGISTER_BUFFERS: 787 case CREATE_OVERLAY: 788 { 789 if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) { 790 IPCThreadState* ipc = IPCThreadState::self(); 791 const int pid = ipc->getCallingPid(); 792 const int uid = ipc->getCallingUid(); 793 LOGE("Permission Denial: " 794 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 795 return PERMISSION_DENIED; 796 } 797 } 798 } 799 return BnSurface::onTransact(code, data, reply, flags); 800 } 801 802 sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) 803 { 804 return NULL; 805 } 806 807 status_t LayerBaseClient::Surface::registerBuffers( 808 const ISurface::BufferHeap& buffers) 809 { 810 return INVALID_OPERATION; 811 } 812 813 void LayerBaseClient::Surface::postBuffer(ssize_t offset) 814 { 815 } 816 817 void LayerBaseClient::Surface::unregisterBuffers() 818 { 819 } 820 821 sp<OverlayRef> LayerBaseClient::Surface::createOverlay( 822 uint32_t w, uint32_t h, int32_t format, int32_t orientation) 823 { 824 return NULL; 825 }; 826 827 // --------------------------------------------------------------------------- 828 829 }; // namespace android 830