LayerBase.cpp revision 78fd5010a87425d2be401d10a306dd68638fc1dd
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 37namespace android { 38 39// --------------------------------------------------------------------------- 40 41const uint32_t LayerBase::typeInfo = 1; 42const char* const LayerBase::typeID = "LayerBase"; 43 44const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2; 45const char* const LayerBaseClient::typeID = "LayerBaseClient"; 46 47// --------------------------------------------------------------------------- 48 49LayerBase::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 64LayerBase::~LayerBase() 65{ 66} 67 68void LayerBase::setName(const String8& name) { 69 mName = name; 70} 71 72String8 LayerBase::getName() const { 73 return mName; 74} 75 76const GraphicPlane& LayerBase::graphicPlane(int dpy) const 77{ 78 return mFlinger->graphicPlane(dpy); 79} 80 81GraphicPlane& LayerBase::graphicPlane(int dpy) 82{ 83 return mFlinger->graphicPlane(dpy); 84} 85 86void 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 109void LayerBase::commitTransaction() { 110 mDrawingState = mCurrentState; 111} 112void 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} 118bool LayerBase::requestTransaction() { 119 int32_t old = setTransactionFlags(eTransactionNeeded); 120 return ((old & eTransactionNeeded) == 0); 121} 122uint32_t LayerBase::getTransactionFlags(uint32_t flags) { 123 return android_atomic_and(~flags, &mTransactionFlags) & flags; 124} 125uint32_t LayerBase::setTransactionFlags(uint32_t flags) { 126 return android_atomic_or(flags, &mTransactionFlags); 127} 128 129bool 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} 137bool 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} 145bool 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} 153bool 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} 161bool 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} 169bool 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} 176bool 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 186Rect LayerBase::visibleBounds() const 187{ 188 return mTransformedBounds; 189} 190 191void LayerBase::setVisibleRegion(const Region& visibleRegion) { 192 // always called from main thread 193 visibleRegionScreen = visibleRegion; 194} 195 196void LayerBase::setCoveredRegion(const Region& coveredRegion) { 197 // always called from main thread 198 coveredRegionScreen = coveredRegion; 199} 200 201uint32_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 240void 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 275void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 276{ 277} 278 279void 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 287void LayerBase::finishPageFlip() 288{ 289} 290 291void LayerBase::invalidate() 292{ 293 if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 294 mFlinger->signalEvent(); 295 } 296} 297 298void 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 319void 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 351GLuint 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 363void 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_FLOAT, 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 386void LayerBase::clearWithOpenGL(const Region& clip) const 387{ 388 clearWithOpenGL(clip,0,0,0,0); 389} 390 391void 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 GLfloat alpha = s.alpha * (1.0f/255.0f); 422 glColor4f(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 glColor4f(1, 1, 1, 1); 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 const GLfloat texCoords[4][2] = { 441 { 0, 0 }, 442 { 0, 1 }, 443 { 1, 1 }, 444 { 1, 0 } 445 }; 446 447 glMatrixMode(GL_TEXTURE); 448 glLoadIdentity(); 449 450 // the texture's source is rotated 451 switch (texture.transform) { 452 case HAL_TRANSFORM_ROT_90: 453 glTranslatef(0, 1, 0); 454 glRotatef(-90, 0, 0, 1); 455 break; 456 case HAL_TRANSFORM_ROT_180: 457 glTranslatef(1, 1, 0); 458 glRotatef(-180, 0, 0, 1); 459 break; 460 case HAL_TRANSFORM_ROT_270: 461 glTranslatef(1, 0, 0); 462 glRotatef(-270, 0, 0, 1); 463 break; 464 } 465 466 if (texture.NPOTAdjust) { 467 glScalef(texture.wScale, texture.hScale, 1.0f); 468 } 469 470 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 471 glVertexPointer(2, GL_FLOAT, 0, mVertices); 472 glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 473 474 while (it != end) { 475 const Rect& r = *it++; 476 const GLint sy = fbHeight - (r.top + r.height()); 477 glScissor(r.left, sy, r.width(), r.height()); 478 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 479 } 480 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 481} 482 483void LayerBase::validateTexture(GLint textureName) const 484{ 485 glBindTexture(GL_TEXTURE_2D, textureName); 486 // TODO: reload the texture if needed 487 // this is currently done in loadTexture() below 488 if (mUseLinearFiltering) { 489 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 490 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 491 } else { 492 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 493 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 494 } 495 496 if (needsDithering()) { 497 glEnable(GL_DITHER); 498 } else { 499 glDisable(GL_DITHER); 500 } 501} 502 503bool LayerBase::isSupportedYuvFormat(int format) const 504{ 505 switch (format) { 506 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 507 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 508 case HAL_PIXEL_FORMAT_YCbCr_422_P: 509 case HAL_PIXEL_FORMAT_YCbCr_420_P: 510 case HAL_PIXEL_FORMAT_YCbCr_422_I: 511 case HAL_PIXEL_FORMAT_YCbCr_420_I: 512 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 513 return true; 514 } 515 return false; 516} 517 518void LayerBase::loadTexture(Texture* texture, 519 const Region& dirty, const GGLSurface& t) const 520{ 521 if (texture->name == -1U) { 522 // uh? 523 return; 524 } 525 526 glBindTexture(GL_TEXTURE_2D, texture->name); 527 528 /* 529 * In OpenGL ES we can't specify a stride with glTexImage2D (however, 530 * GL_UNPACK_ALIGNMENT is a limited form of stride). 531 * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we 532 * need to do something reasonable (here creating a bigger texture). 533 * 534 * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT); 535 * 536 * This situation doesn't happen often, but some h/w have a limitation 537 * for their framebuffer (eg: must be multiple of 8 pixels), and 538 * we need to take that into account when using these buffers as 539 * textures. 540 * 541 * This should never be a problem with POT textures 542 */ 543 544 int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format)); 545 unpack = 1 << ((unpack > 3) ? 3 : unpack); 546 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); 547 548 /* 549 * round to POT if needed 550 */ 551 if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { 552 texture->NPOTAdjust = true; 553 } 554 555 if (texture->NPOTAdjust) { 556 // find the smallest power-of-two that will accommodate our surface 557 texture->potWidth = 1 << (31 - clz(t.width)); 558 texture->potHeight = 1 << (31 - clz(t.height)); 559 if (texture->potWidth < t.width) texture->potWidth <<= 1; 560 if (texture->potHeight < t.height) texture->potHeight <<= 1; 561 texture->wScale = float(t.width) / texture->potWidth; 562 texture->hScale = float(t.height) / texture->potHeight; 563 } else { 564 texture->potWidth = t.width; 565 texture->potHeight = t.height; 566 } 567 568 Rect bounds(dirty.bounds()); 569 GLvoid* data = 0; 570 if (texture->width != t.width || texture->height != t.height) { 571 texture->width = t.width; 572 texture->height = t.height; 573 574 // texture size changed, we need to create a new one 575 bounds.set(Rect(t.width, t.height)); 576 if (t.width == texture->potWidth && 577 t.height == texture->potHeight) { 578 // we can do it one pass 579 data = t.data; 580 } 581 582 if (t.format == HAL_PIXEL_FORMAT_RGB_565) { 583 glTexImage2D(GL_TEXTURE_2D, 0, 584 GL_RGB, texture->potWidth, texture->potHeight, 0, 585 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); 586 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { 587 glTexImage2D(GL_TEXTURE_2D, 0, 588 GL_RGBA, texture->potWidth, texture->potHeight, 0, 589 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); 590 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || 591 t.format == HAL_PIXEL_FORMAT_RGBX_8888) { 592 glTexImage2D(GL_TEXTURE_2D, 0, 593 GL_RGBA, texture->potWidth, texture->potHeight, 0, 594 GL_RGBA, GL_UNSIGNED_BYTE, data); 595 } else if (isSupportedYuvFormat(t.format)) { 596 // just show the Y plane of YUV buffers 597 glTexImage2D(GL_TEXTURE_2D, 0, 598 GL_LUMINANCE, texture->potWidth, texture->potHeight, 0, 599 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 600 } else { 601 // oops, we don't handle this format! 602 LOGE("layer %p, texture=%d, using format %d, which is not " 603 "supported by the GL", this, texture->name, t.format); 604 } 605 } 606 if (!data) { 607 if (t.format == HAL_PIXEL_FORMAT_RGB_565) { 608 glTexSubImage2D(GL_TEXTURE_2D, 0, 609 0, bounds.top, t.width, bounds.height(), 610 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 611 t.data + bounds.top*t.stride*2); 612 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { 613 glTexSubImage2D(GL_TEXTURE_2D, 0, 614 0, bounds.top, t.width, bounds.height(), 615 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 616 t.data + bounds.top*t.stride*2); 617 } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || 618 t.format == HAL_PIXEL_FORMAT_RGBX_8888) { 619 glTexSubImage2D(GL_TEXTURE_2D, 0, 620 0, bounds.top, t.width, bounds.height(), 621 GL_RGBA, GL_UNSIGNED_BYTE, 622 t.data + bounds.top*t.stride*4); 623 } else if (isSupportedYuvFormat(t.format)) { 624 // just show the Y plane of YUV buffers 625 glTexSubImage2D(GL_TEXTURE_2D, 0, 626 0, bounds.top, t.width, bounds.height(), 627 GL_LUMINANCE, GL_UNSIGNED_BYTE, 628 t.data + bounds.top*t.stride); 629 } 630 } 631} 632 633status_t LayerBase::initializeEglImage( 634 const sp<GraphicBuffer>& buffer, Texture* texture) 635{ 636 status_t err = NO_ERROR; 637 638 // we need to recreate the texture 639 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 640 641 // free the previous image 642 if (texture->image != EGL_NO_IMAGE_KHR) { 643 eglDestroyImageKHR(dpy, texture->image); 644 texture->image = EGL_NO_IMAGE_KHR; 645 } 646 647 // construct an EGL_NATIVE_BUFFER_ANDROID 648 android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); 649 650 // create the new EGLImageKHR 651 const EGLint attrs[] = { 652 EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 653 EGL_NONE, EGL_NONE 654 }; 655 texture->image = eglCreateImageKHR( 656 dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, 657 (EGLClientBuffer)clientBuf, attrs); 658 659 if (texture->image != EGL_NO_IMAGE_KHR) { 660 glBindTexture(GL_TEXTURE_2D, texture->name); 661 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 662 (GLeglImageOES)texture->image); 663 GLint error = glGetError(); 664 if (UNLIKELY(error != GL_NO_ERROR)) { 665 LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) " 666 "failed err=0x%04x", 667 this, texture->image, error); 668 err = INVALID_OPERATION; 669 } else { 670 // Everything went okay! 671 texture->NPOTAdjust = false; 672 texture->dirty = false; 673 texture->width = clientBuf->width; 674 texture->height = clientBuf->height; 675 } 676 } else { 677 LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x", 678 this, eglGetError()); 679 err = INVALID_OPERATION; 680 } 681 return err; 682} 683 684 685// --------------------------------------------------------------------------- 686 687int32_t LayerBaseClient::sIdentity = 0; 688 689LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 690 const sp<Client>& client, int32_t i) 691 : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i), 692 mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 693{ 694 lcblk = new SharedBufferServer( 695 client->ctrlblk, i, NUM_BUFFERS, 696 mIdentity); 697} 698 699void LayerBaseClient::onFirstRef() 700{ 701 sp<Client> client(this->client.promote()); 702 if (client != 0) { 703 client->bindLayer(this, mIndex); 704 } 705} 706 707LayerBaseClient::~LayerBaseClient() 708{ 709 sp<Client> client(this->client.promote()); 710 if (client != 0) { 711 client->free(mIndex); 712 } 713 delete lcblk; 714} 715 716int32_t LayerBaseClient::serverIndex() const 717{ 718 sp<Client> client(this->client.promote()); 719 if (client != 0) { 720 return (client->cid<<16)|mIndex; 721 } 722 return 0xFFFF0000 | mIndex; 723} 724 725sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() 726{ 727 sp<Surface> s; 728 Mutex::Autolock _l(mLock); 729 s = mClientSurface.promote(); 730 if (s == 0) { 731 s = createSurface(); 732 mClientSurface = s; 733 } 734 return s; 735} 736 737sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const 738{ 739 return new Surface(mFlinger, clientIndex(), mIdentity, 740 const_cast<LayerBaseClient *>(this)); 741} 742 743// called with SurfaceFlinger::mStateLock as soon as the layer is entered 744// in the purgatory list 745void LayerBaseClient::onRemoved() 746{ 747 // wake up the condition 748 lcblk->setStatus(NO_INIT); 749} 750 751// --------------------------------------------------------------------------- 752 753LayerBaseClient::Surface::Surface( 754 const sp<SurfaceFlinger>& flinger, 755 SurfaceID id, int identity, 756 const sp<LayerBaseClient>& owner) 757 : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner) 758{ 759} 760 761LayerBaseClient::Surface::~Surface() 762{ 763 /* 764 * This is a good place to clean-up all client resources 765 */ 766 767 // destroy client resources 768 sp<LayerBaseClient> layer = getOwner(); 769 if (layer != 0) { 770 mFlinger->destroySurface(layer); 771 } 772} 773 774sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const { 775 sp<LayerBaseClient> owner(mOwner.promote()); 776 return owner; 777} 778 779status_t LayerBaseClient::Surface::onTransact( 780 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 781{ 782 switch (code) { 783 case REGISTER_BUFFERS: 784 case UNREGISTER_BUFFERS: 785 case CREATE_OVERLAY: 786 { 787 if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) { 788 IPCThreadState* ipc = IPCThreadState::self(); 789 const int pid = ipc->getCallingPid(); 790 const int uid = ipc->getCallingUid(); 791 LOGE("Permission Denial: " 792 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 793 return PERMISSION_DENIED; 794 } 795 } 796 } 797 return BnSurface::onTransact(code, data, reply, flags); 798} 799 800sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) 801{ 802 return NULL; 803} 804 805status_t LayerBaseClient::Surface::registerBuffers( 806 const ISurface::BufferHeap& buffers) 807{ 808 return INVALID_OPERATION; 809} 810 811void LayerBaseClient::Surface::postBuffer(ssize_t offset) 812{ 813} 814 815void LayerBaseClient::Surface::unregisterBuffers() 816{ 817} 818 819sp<OverlayRef> LayerBaseClient::Surface::createOverlay( 820 uint32_t w, uint32_t h, int32_t format, int32_t orientation) 821{ 822 return NULL; 823}; 824 825// --------------------------------------------------------------------------- 826 827}; // namespace android 828