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 #include "TextureManager.h" 36 37 38 namespace android { 39 40 // --------------------------------------------------------------------------- 41 42 int32_t LayerBase::sSequence = 1; 43 44 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) 45 : dpy(display), contentDirty(false), 46 sequence(uint32_t(android_atomic_inc(&sSequence))), 47 mFlinger(flinger), 48 mNeedsFiltering(false), 49 mOrientation(0), 50 mLeft(0), mTop(0), 51 mTransactionFlags(0), 52 mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), 53 mInvalidate(0) 54 { 55 const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); 56 mFlags = hw.getFlags(); 57 mBufferCrop.makeInvalid(); 58 mBufferTransform = 0; 59 } 60 61 LayerBase::~LayerBase() 62 { 63 } 64 65 void LayerBase::setName(const String8& name) { 66 mName = name; 67 } 68 69 String8 LayerBase::getName() const { 70 return mName; 71 } 72 73 const GraphicPlane& LayerBase::graphicPlane(int dpy) const 74 { 75 return mFlinger->graphicPlane(dpy); 76 } 77 78 GraphicPlane& LayerBase::graphicPlane(int dpy) 79 { 80 return mFlinger->graphicPlane(dpy); 81 } 82 83 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) 84 { 85 uint32_t layerFlags = 0; 86 if (flags & ISurfaceComposer::eHidden) 87 layerFlags = ISurfaceComposer::eLayerHidden; 88 89 if (flags & ISurfaceComposer::eNonPremultiplied) 90 mPremultipliedAlpha = false; 91 92 mCurrentState.z = 0; 93 mCurrentState.w = w; 94 mCurrentState.h = h; 95 mCurrentState.requested_w = w; 96 mCurrentState.requested_h = h; 97 mCurrentState.alpha = 0xFF; 98 mCurrentState.flags = layerFlags; 99 mCurrentState.sequence = 0; 100 mCurrentState.transform.set(0, 0); 101 102 // drawing state & current state are identical 103 mDrawingState = mCurrentState; 104 } 105 106 void LayerBase::commitTransaction() { 107 mDrawingState = mCurrentState; 108 } 109 void LayerBase::forceVisibilityTransaction() { 110 // this can be called without SurfaceFlinger.mStateLock, but if we 111 // can atomically increment the sequence number, it doesn't matter. 112 android_atomic_inc(&mCurrentState.sequence); 113 requestTransaction(); 114 } 115 bool LayerBase::requestTransaction() { 116 int32_t old = setTransactionFlags(eTransactionNeeded); 117 return ((old & eTransactionNeeded) == 0); 118 } 119 uint32_t LayerBase::getTransactionFlags(uint32_t flags) { 120 return android_atomic_and(~flags, &mTransactionFlags) & flags; 121 } 122 uint32_t LayerBase::setTransactionFlags(uint32_t flags) { 123 return android_atomic_or(flags, &mTransactionFlags); 124 } 125 126 bool LayerBase::setPosition(int32_t x, int32_t y) { 127 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 128 return false; 129 mCurrentState.sequence++; 130 mCurrentState.transform.set(x, y); 131 requestTransaction(); 132 return true; 133 } 134 bool LayerBase::setLayer(uint32_t z) { 135 if (mCurrentState.z == z) 136 return false; 137 mCurrentState.sequence++; 138 mCurrentState.z = z; 139 requestTransaction(); 140 return true; 141 } 142 bool LayerBase::setSize(uint32_t w, uint32_t h) { 143 if (mCurrentState.requested_w == w && mCurrentState.requested_h == h) 144 return false; 145 mCurrentState.requested_w = w; 146 mCurrentState.requested_h = h; 147 requestTransaction(); 148 return true; 149 } 150 bool LayerBase::setAlpha(uint8_t alpha) { 151 if (mCurrentState.alpha == alpha) 152 return false; 153 mCurrentState.sequence++; 154 mCurrentState.alpha = alpha; 155 requestTransaction(); 156 return true; 157 } 158 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) { 159 mCurrentState.sequence++; 160 mCurrentState.transform.set( 161 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 162 requestTransaction(); 163 return true; 164 } 165 bool LayerBase::setTransparentRegionHint(const Region& transparent) { 166 mCurrentState.sequence++; 167 mCurrentState.transparentRegion = transparent; 168 requestTransaction(); 169 return true; 170 } 171 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) { 172 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 173 if (mCurrentState.flags == newFlags) 174 return false; 175 mCurrentState.sequence++; 176 mCurrentState.flags = newFlags; 177 requestTransaction(); 178 return true; 179 } 180 181 Rect LayerBase::visibleBounds() const 182 { 183 return mTransformedBounds; 184 } 185 186 void LayerBase::setVisibleRegion(const Region& visibleRegion) { 187 // always called from main thread 188 visibleRegionScreen = visibleRegion; 189 } 190 191 void LayerBase::setCoveredRegion(const Region& coveredRegion) { 192 // always called from main thread 193 coveredRegionScreen = coveredRegion; 194 } 195 196 uint32_t LayerBase::doTransaction(uint32_t flags) 197 { 198 const Layer::State& front(drawingState()); 199 const Layer::State& temp(currentState()); 200 201 if ((front.requested_w != temp.requested_w) || 202 (front.requested_h != temp.requested_h)) { 203 // resize the layer, set the physical size to the requested size 204 Layer::State& editTemp(currentState()); 205 editTemp.w = temp.requested_w; 206 editTemp.h = temp.requested_h; 207 } 208 209 if ((front.w != temp.w) || (front.h != temp.h)) { 210 // invalidate and recompute the visible regions if needed 211 flags |= Layer::eVisibleRegion; 212 } 213 214 if (temp.sequence != front.sequence) { 215 // invalidate and recompute the visible regions if needed 216 flags |= eVisibleRegion; 217 this->contentDirty = true; 218 219 // we may use linear filtering, if the matrix scales us 220 const uint8_t type = temp.transform.getType(); 221 mNeedsFiltering = (!temp.transform.preserveRects() || 222 (type >= Transform::SCALE)); 223 } 224 225 // Commit the transaction 226 commitTransaction(); 227 return flags; 228 } 229 230 void LayerBase::validateVisibility(const Transform& planeTransform) 231 { 232 const Layer::State& s(drawingState()); 233 const Transform tr(planeTransform * s.transform); 234 const bool transformed = tr.transformed(); 235 236 uint32_t w = s.w; 237 uint32_t h = s.h; 238 tr.transform(mVertices[0], 0, 0); 239 tr.transform(mVertices[1], 0, h); 240 tr.transform(mVertices[2], w, h); 241 tr.transform(mVertices[3], w, 0); 242 if (UNLIKELY(transformed)) { 243 // NOTE: here we could also punt if we have too many rectangles 244 // in the transparent region 245 if (tr.preserveRects()) { 246 // transform the transparent region 247 transparentRegionScreen = tr.transform(s.transparentRegion); 248 } else { 249 // transformation too complex, can't do the transparent region 250 // optimization. 251 transparentRegionScreen.clear(); 252 } 253 } else { 254 transparentRegionScreen = s.transparentRegion; 255 } 256 257 // cache a few things... 258 mOrientation = tr.getOrientation(); 259 mTransformedBounds = tr.makeBounds(w, h); 260 mLeft = tr.tx(); 261 mTop = tr.ty(); 262 } 263 264 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 265 { 266 } 267 268 void LayerBase::unlockPageFlip( 269 const Transform& planeTransform, Region& outDirtyRegion) 270 { 271 if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { 272 outDirtyRegion.orSelf(visibleRegionScreen); 273 } 274 } 275 276 void LayerBase::invalidate() 277 { 278 if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 279 mFlinger->signalEvent(); 280 } 281 } 282 283 void LayerBase::drawRegion(const Region& reg) const 284 { 285 Region::const_iterator it = reg.begin(); 286 Region::const_iterator const end = reg.end(); 287 if (it != end) { 288 Rect r; 289 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 290 const int32_t fbWidth = hw.getWidth(); 291 const int32_t fbHeight = hw.getHeight(); 292 const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 293 { fbWidth, fbHeight }, { 0, fbHeight } }; 294 glVertexPointer(2, GL_SHORT, 0, vertices); 295 while (it != end) { 296 const Rect& r = *it++; 297 const GLint sy = fbHeight - (r.top + r.height()); 298 glScissor(r.left, sy, r.width(), r.height()); 299 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 300 } 301 } 302 } 303 304 void LayerBase::draw(const Region& clip) const 305 { 306 // reset GL state 307 glEnable(GL_SCISSOR_TEST); 308 309 onDraw(clip); 310 } 311 312 void LayerBase::drawForSreenShot() const 313 { 314 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 315 onDraw( Region(hw.bounds()) ); 316 } 317 318 void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red, 319 GLclampf green, GLclampf blue, 320 GLclampf alpha) const 321 { 322 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 323 const uint32_t fbHeight = hw.getHeight(); 324 glColor4f(red,green,blue,alpha); 325 326 TextureManager::deactivateTextures(); 327 328 glDisable(GL_BLEND); 329 glDisable(GL_DITHER); 330 331 Region::const_iterator it = clip.begin(); 332 Region::const_iterator const end = clip.end(); 333 glEnable(GL_SCISSOR_TEST); 334 glVertexPointer(2, GL_FLOAT, 0, mVertices); 335 while (it != end) { 336 const Rect& r = *it++; 337 const GLint sy = fbHeight - (r.top + r.height()); 338 glScissor(r.left, sy, r.width(), r.height()); 339 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 340 } 341 } 342 343 void LayerBase::clearWithOpenGL(const Region& clip) const 344 { 345 clearWithOpenGL(clip,0,0,0,0); 346 } 347 348 template <typename T> 349 static inline 350 void swap(T& a, T& b) { 351 T t(a); 352 a = b; 353 b = t; 354 } 355 356 void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const 357 { 358 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 359 const uint32_t fbHeight = hw.getHeight(); 360 const State& s(drawingState()); 361 362 // bind our texture 363 TextureManager::activateTexture(texture, needsFiltering()); 364 uint32_t width = texture.width; 365 uint32_t height = texture.height; 366 367 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 368 if (UNLIKELY(s.alpha < 0xFF)) { 369 const GLfloat alpha = s.alpha * (1.0f/255.0f); 370 if (mPremultipliedAlpha) { 371 glColor4f(alpha, alpha, alpha, alpha); 372 } else { 373 glColor4f(1, 1, 1, alpha); 374 } 375 glEnable(GL_BLEND); 376 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 377 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 378 } else { 379 glColor4f(1, 1, 1, 1); 380 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 381 if (needsBlending()) { 382 glEnable(GL_BLEND); 383 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 384 } else { 385 glDisable(GL_BLEND); 386 } 387 } 388 389 /* 390 * compute texture coordinates 391 * here, we handle NPOT, cropping and buffer transformations 392 */ 393 394 GLfloat cl, ct, cr, cb; 395 if (!mBufferCrop.isEmpty()) { 396 // source is cropped 397 const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width; 398 const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height; 399 cl = mBufferCrop.left * us; 400 ct = mBufferCrop.top * vs; 401 cr = mBufferCrop.right * us; 402 cb = mBufferCrop.bottom * vs; 403 } else { 404 cl = 0; 405 ct = 0; 406 cr = (texture.NPOTAdjust ? texture.wScale : 1.0f); 407 cb = (texture.NPOTAdjust ? texture.hScale : 1.0f); 408 } 409 410 /* 411 * For the buffer transformation, we apply the rotation last. 412 * Since we're transforming the texture-coordinates, we need 413 * to apply the inverse of the buffer transformation: 414 * inverse( FLIP_V -> FLIP_H -> ROT_90 ) 415 * <=> inverse( ROT_90 * FLIP_H * FLIP_V ) 416 * = inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90) 417 * = FLIP_V * FLIP_H * ROT_270 418 * <=> ROT_270 -> FLIP_H -> FLIP_V 419 * 420 * The rotation is performed first, in the texture coordinate space. 421 * 422 */ 423 424 struct TexCoords { 425 GLfloat u; 426 GLfloat v; 427 }; 428 429 enum { 430 // name of the corners in the texture map 431 LB = 0, // left-bottom 432 LT = 1, // left-top 433 RT = 2, // right-top 434 RB = 3 // right-bottom 435 }; 436 437 // vertices in screen space 438 int vLT = LB; 439 int vLB = LT; 440 int vRB = RT; 441 int vRT = RB; 442 443 // the texture's source is rotated 444 uint32_t transform = mBufferTransform; 445 if (transform & HAL_TRANSFORM_ROT_90) { 446 vLT = RB; 447 vLB = LB; 448 vRB = LT; 449 vRT = RT; 450 } 451 if (transform & HAL_TRANSFORM_FLIP_V) { 452 swap(vLT, vLB); 453 swap(vRT, vRB); 454 } 455 if (transform & HAL_TRANSFORM_FLIP_H) { 456 swap(vLT, vRT); 457 swap(vLB, vRB); 458 } 459 460 TexCoords texCoords[4]; 461 texCoords[vLT].u = cl; 462 texCoords[vLT].v = ct; 463 texCoords[vLB].u = cl; 464 texCoords[vLB].v = cb; 465 texCoords[vRB].u = cr; 466 texCoords[vRB].v = cb; 467 texCoords[vRT].u = cr; 468 texCoords[vRT].v = ct; 469 470 if (needsDithering()) { 471 glEnable(GL_DITHER); 472 } else { 473 glDisable(GL_DITHER); 474 } 475 476 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 477 glVertexPointer(2, GL_FLOAT, 0, mVertices); 478 glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 479 480 Region::const_iterator it = clip.begin(); 481 Region::const_iterator const end = clip.end(); 482 while (it != end) { 483 const Rect& r = *it++; 484 const GLint sy = fbHeight - (r.top + r.height()); 485 glScissor(r.left, sy, r.width(), r.height()); 486 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 487 } 488 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 489 } 490 491 void LayerBase::setBufferCrop(const Rect& crop) { 492 if (!crop.isEmpty()) { 493 mBufferCrop = crop; 494 } 495 } 496 497 void LayerBase::setBufferTransform(uint32_t transform) { 498 mBufferTransform = transform; 499 } 500 501 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const 502 { 503 const Layer::State& s(drawingState()); 504 snprintf(buffer, SIZE, 505 "+ %s %p\n" 506 " " 507 "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), " 508 "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, " 509 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", 510 getTypeId(), this, s.z, tx(), ty(), s.w, s.h, 511 needsBlending(), needsDithering(), contentDirty, 512 s.alpha, s.flags, 513 s.transform[0][0], s.transform[0][1], 514 s.transform[1][0], s.transform[1][1]); 515 result.append(buffer); 516 } 517 518 // --------------------------------------------------------------------------- 519 520 int32_t LayerBaseClient::sIdentity = 1; 521 522 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 523 const sp<Client>& client) 524 : LayerBase(flinger, display), mClientRef(client), 525 mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 526 { 527 } 528 529 LayerBaseClient::~LayerBaseClient() 530 { 531 sp<Client> c(mClientRef.promote()); 532 if (c != 0) { 533 c->detachLayer(this); 534 } 535 } 536 537 sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() 538 { 539 sp<Surface> s; 540 Mutex::Autolock _l(mLock); 541 s = mClientSurface.promote(); 542 if (s == 0) { 543 s = createSurface(); 544 mClientSurface = s; 545 } 546 return s; 547 } 548 549 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const 550 { 551 return new Surface(mFlinger, mIdentity, 552 const_cast<LayerBaseClient *>(this)); 553 } 554 555 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const 556 { 557 LayerBase::dump(result, buffer, SIZE); 558 559 sp<Client> client(mClientRef.promote()); 560 snprintf(buffer, SIZE, 561 " name=%s\n" 562 " client=%p, identity=%u\n", 563 getName().string(), 564 client.get(), getIdentity()); 565 566 result.append(buffer); 567 } 568 569 // --------------------------------------------------------------------------- 570 571 LayerBaseClient::Surface::Surface( 572 const sp<SurfaceFlinger>& flinger, 573 int identity, 574 const sp<LayerBaseClient>& owner) 575 : mFlinger(flinger), mIdentity(identity), mOwner(owner) 576 { 577 } 578 579 LayerBaseClient::Surface::~Surface() 580 { 581 /* 582 * This is a good place to clean-up all client resources 583 */ 584 585 // destroy client resources 586 mFlinger->destroySurface(mOwner); 587 } 588 589 sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const { 590 sp<LayerBaseClient> owner(mOwner.promote()); 591 return owner; 592 } 593 594 status_t LayerBaseClient::Surface::onTransact( 595 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 596 { 597 switch (code) { 598 case REGISTER_BUFFERS: 599 case UNREGISTER_BUFFERS: 600 case CREATE_OVERLAY: 601 { 602 if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) { 603 IPCThreadState* ipc = IPCThreadState::self(); 604 const int pid = ipc->getCallingPid(); 605 const int uid = ipc->getCallingUid(); 606 LOGE("Permission Denial: " 607 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 608 return PERMISSION_DENIED; 609 } 610 } 611 } 612 return BnSurface::onTransact(code, data, reply, flags); 613 } 614 615 sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int bufferIdx, 616 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 617 { 618 return NULL; 619 } 620 621 status_t LayerBaseClient::Surface::setBufferCount(int bufferCount) 622 { 623 return INVALID_OPERATION; 624 } 625 626 status_t LayerBaseClient::Surface::registerBuffers( 627 const ISurface::BufferHeap& buffers) 628 { 629 return INVALID_OPERATION; 630 } 631 632 void LayerBaseClient::Surface::postBuffer(ssize_t offset) 633 { 634 } 635 636 void LayerBaseClient::Surface::unregisterBuffers() 637 { 638 } 639 640 sp<OverlayRef> LayerBaseClient::Surface::createOverlay( 641 uint32_t w, uint32_t h, int32_t format, int32_t orientation) 642 { 643 return NULL; 644 }; 645 646 // --------------------------------------------------------------------------- 647 648 }; // namespace android 649