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 namespace android { 37 38 // --------------------------------------------------------------------------- 39 40 int32_t LayerBase::sSequence = 1; 41 42 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) 43 : dpy(display), contentDirty(false), 44 sequence(uint32_t(android_atomic_inc(&sSequence))), 45 mFlinger(flinger), mFiltering(false), 46 mNeedsFiltering(false), mInOverlay(false), 47 mOrientation(0), 48 mPlaneOrientation(0), 49 mTransactionFlags(0), 50 mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), 51 mInvalidate(0) 52 { 53 const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); 54 mFlags = hw.getFlags(); 55 } 56 57 LayerBase::~LayerBase() 58 { 59 } 60 61 void LayerBase::setName(const String8& name) { 62 mName = name; 63 } 64 65 String8 LayerBase::getName() const { 66 return mName; 67 } 68 69 const GraphicPlane& LayerBase::graphicPlane(int dpy) const 70 { 71 return mFlinger->graphicPlane(dpy); 72 } 73 74 GraphicPlane& LayerBase::graphicPlane(int dpy) 75 { 76 return mFlinger->graphicPlane(dpy); 77 } 78 79 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) 80 { 81 uint32_t layerFlags = 0; 82 if (flags & ISurfaceComposer::eHidden) 83 layerFlags = ISurfaceComposer::eLayerHidden; 84 85 if (flags & ISurfaceComposer::eNonPremultiplied) 86 mPremultipliedAlpha = false; 87 88 mCurrentState.z = 0; 89 mCurrentState.w = w; 90 mCurrentState.h = h; 91 mCurrentState.requested_w = w; 92 mCurrentState.requested_h = h; 93 mCurrentState.alpha = 0xFF; 94 mCurrentState.flags = layerFlags; 95 mCurrentState.sequence = 0; 96 mCurrentState.transform.set(0, 0); 97 98 // drawing state & current state are identical 99 mDrawingState = mCurrentState; 100 } 101 102 void LayerBase::commitTransaction() { 103 mDrawingState = mCurrentState; 104 } 105 void LayerBase::forceVisibilityTransaction() { 106 // this can be called without SurfaceFlinger.mStateLock, but if we 107 // can atomically increment the sequence number, it doesn't matter. 108 android_atomic_inc(&mCurrentState.sequence); 109 requestTransaction(); 110 } 111 bool LayerBase::requestTransaction() { 112 int32_t old = setTransactionFlags(eTransactionNeeded); 113 return ((old & eTransactionNeeded) == 0); 114 } 115 uint32_t LayerBase::getTransactionFlags(uint32_t flags) { 116 return android_atomic_and(~flags, &mTransactionFlags) & flags; 117 } 118 uint32_t LayerBase::setTransactionFlags(uint32_t flags) { 119 return android_atomic_or(flags, &mTransactionFlags); 120 } 121 122 bool LayerBase::setPosition(float x, float y) { 123 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 124 return false; 125 mCurrentState.sequence++; 126 mCurrentState.transform.set(x, y); 127 requestTransaction(); 128 return true; 129 } 130 bool LayerBase::setLayer(uint32_t z) { 131 if (mCurrentState.z == z) 132 return false; 133 mCurrentState.sequence++; 134 mCurrentState.z = z; 135 requestTransaction(); 136 return true; 137 } 138 bool LayerBase::setSize(uint32_t w, uint32_t h) { 139 if (mCurrentState.requested_w == w && mCurrentState.requested_h == h) 140 return false; 141 mCurrentState.requested_w = w; 142 mCurrentState.requested_h = h; 143 requestTransaction(); 144 return true; 145 } 146 bool LayerBase::setAlpha(uint8_t alpha) { 147 if (mCurrentState.alpha == alpha) 148 return false; 149 mCurrentState.sequence++; 150 mCurrentState.alpha = alpha; 151 requestTransaction(); 152 return true; 153 } 154 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) { 155 mCurrentState.sequence++; 156 mCurrentState.transform.set( 157 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 158 requestTransaction(); 159 return true; 160 } 161 bool LayerBase::setTransparentRegionHint(const Region& transparent) { 162 mCurrentState.sequence++; 163 mCurrentState.transparentRegion = transparent; 164 requestTransaction(); 165 return true; 166 } 167 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) { 168 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 169 if (mCurrentState.flags == newFlags) 170 return false; 171 mCurrentState.sequence++; 172 mCurrentState.flags = newFlags; 173 requestTransaction(); 174 return true; 175 } 176 177 Rect LayerBase::visibleBounds() const 178 { 179 return mTransformedBounds; 180 } 181 182 void LayerBase::setVisibleRegion(const Region& visibleRegion) { 183 // always called from main thread 184 visibleRegionScreen = visibleRegion; 185 } 186 187 void LayerBase::setCoveredRegion(const Region& coveredRegion) { 188 // always called from main thread 189 coveredRegionScreen = coveredRegion; 190 } 191 192 uint32_t LayerBase::doTransaction(uint32_t flags) 193 { 194 const Layer::State& front(drawingState()); 195 const Layer::State& temp(currentState()); 196 197 if ((front.requested_w != temp.requested_w) || 198 (front.requested_h != temp.requested_h)) { 199 // resize the layer, set the physical size to the requested size 200 Layer::State& editTemp(currentState()); 201 editTemp.w = temp.requested_w; 202 editTemp.h = temp.requested_h; 203 } 204 205 if ((front.w != temp.w) || (front.h != temp.h)) { 206 // invalidate and recompute the visible regions if needed 207 flags |= Layer::eVisibleRegion; 208 } 209 210 if (temp.sequence != front.sequence) { 211 // invalidate and recompute the visible regions if needed 212 flags |= eVisibleRegion; 213 this->contentDirty = true; 214 215 // we may use linear filtering, if the matrix scales us 216 const uint8_t type = temp.transform.getType(); 217 mNeedsFiltering = (!temp.transform.preserveRects() || 218 (type >= Transform::SCALE)); 219 } 220 221 // Commit the transaction 222 commitTransaction(); 223 return flags; 224 } 225 226 void LayerBase::validateVisibility(const Transform& planeTransform) 227 { 228 const Layer::State& s(drawingState()); 229 const Transform tr(planeTransform * s.transform); 230 const bool transformed = tr.transformed(); 231 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 232 const uint32_t hw_h = hw.getHeight(); 233 234 uint32_t w = s.w; 235 uint32_t h = s.h; 236 tr.transform(mVertices[0], 0, 0); 237 tr.transform(mVertices[1], 0, h); 238 tr.transform(mVertices[2], w, h); 239 tr.transform(mVertices[3], w, 0); 240 for (size_t i=0 ; i<4 ; i++) 241 mVertices[i][1] = hw_h - mVertices[i][1]; 242 243 if (UNLIKELY(transformed)) { 244 // NOTE: here we could also punt if we have too many rectangles 245 // in the transparent region 246 if (tr.preserveRects()) { 247 // transform the transparent region 248 transparentRegionScreen = tr.transform(s.transparentRegion); 249 } else { 250 // transformation too complex, can't do the transparent region 251 // optimization. 252 transparentRegionScreen.clear(); 253 } 254 } else { 255 transparentRegionScreen = s.transparentRegion; 256 } 257 258 // cache a few things... 259 mOrientation = tr.getOrientation(); 260 mPlaneOrientation = planeTransform.getOrientation(); 261 mTransform = tr; 262 mTransformedBounds = tr.makeBounds(w, h); 263 } 264 265 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 266 { 267 } 268 269 void LayerBase::unlockPageFlip( 270 const Transform& planeTransform, Region& outDirtyRegion) 271 { 272 if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { 273 outDirtyRegion.orSelf(visibleRegionScreen); 274 } 275 } 276 277 void LayerBase::invalidate() 278 { 279 if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 280 mFlinger->signalEvent(); 281 } 282 } 283 284 void LayerBase::drawRegion(const Region& reg) const 285 { 286 Region::const_iterator it = reg.begin(); 287 Region::const_iterator const end = reg.end(); 288 if (it != end) { 289 Rect r; 290 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 291 const int32_t fbWidth = hw.getWidth(); 292 const int32_t fbHeight = hw.getHeight(); 293 const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 294 { fbWidth, fbHeight }, { 0, fbHeight } }; 295 glVertexPointer(2, GL_SHORT, 0, vertices); 296 while (it != end) { 297 const Rect& r = *it++; 298 const GLint sy = fbHeight - (r.top + r.height()); 299 glScissor(r.left, sy, r.width(), r.height()); 300 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 301 } 302 } 303 } 304 305 void LayerBase::setGeometry(hwc_layer_t* hwcl) 306 { 307 hwcl->compositionType = HWC_FRAMEBUFFER; 308 hwcl->hints = 0; 309 hwcl->flags = HWC_SKIP_LAYER; 310 hwcl->transform = 0; 311 hwcl->blending = HWC_BLENDING_NONE; 312 313 // this gives us only the "orientation" component of the transform 314 const State& s(drawingState()); 315 const uint32_t finalTransform = s.transform.getOrientation(); 316 // we can only handle simple transformation 317 if (finalTransform & Transform::ROT_INVALID) { 318 hwcl->flags = HWC_SKIP_LAYER; 319 } else { 320 hwcl->transform = finalTransform; 321 } 322 323 if (!isOpaque()) { 324 hwcl->blending = mPremultipliedAlpha ? 325 HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE; 326 } 327 328 // scaling is already applied in mTransformedBounds 329 hwcl->displayFrame.left = mTransformedBounds.left; 330 hwcl->displayFrame.top = mTransformedBounds.top; 331 hwcl->displayFrame.right = mTransformedBounds.right; 332 hwcl->displayFrame.bottom = mTransformedBounds.bottom; 333 hwcl->visibleRegionScreen.rects = 334 reinterpret_cast<hwc_rect_t const *>( 335 visibleRegionScreen.getArray( 336 &hwcl->visibleRegionScreen.numRects)); 337 338 hwcl->sourceCrop.left = 0; 339 hwcl->sourceCrop.top = 0; 340 hwcl->sourceCrop.right = mTransformedBounds.width(); 341 hwcl->sourceCrop.bottom = mTransformedBounds.height(); 342 } 343 344 void LayerBase::setPerFrameData(hwc_layer_t* hwcl) { 345 hwcl->compositionType = HWC_FRAMEBUFFER; 346 hwcl->handle = NULL; 347 } 348 349 void LayerBase::setOverlay(bool inOverlay) { 350 mInOverlay = inOverlay; 351 } 352 353 bool LayerBase::isOverlay() const { 354 return mInOverlay; 355 } 356 357 void LayerBase::setFiltering(bool filtering) 358 { 359 mFiltering = filtering; 360 } 361 362 bool LayerBase::getFiltering() const 363 { 364 return mFiltering; 365 } 366 367 void LayerBase::draw(const Region& clip) const 368 { 369 // reset GL state 370 glEnable(GL_SCISSOR_TEST); 371 372 onDraw(clip); 373 } 374 375 void LayerBase::drawForSreenShot() 376 { 377 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 378 setFiltering(true); 379 onDraw( Region(hw.bounds()) ); 380 setFiltering(false); 381 } 382 383 void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red, 384 GLclampf green, GLclampf blue, 385 GLclampf alpha) const 386 { 387 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 388 const uint32_t fbHeight = hw.getHeight(); 389 glColor4f(red,green,blue,alpha); 390 391 glDisable(GL_TEXTURE_EXTERNAL_OES); 392 glDisable(GL_TEXTURE_2D); 393 glDisable(GL_BLEND); 394 395 Region::const_iterator it = clip.begin(); 396 Region::const_iterator const end = clip.end(); 397 glEnable(GL_SCISSOR_TEST); 398 glVertexPointer(2, GL_FLOAT, 0, mVertices); 399 while (it != end) { 400 const Rect& r = *it++; 401 const GLint sy = fbHeight - (r.top + r.height()); 402 glScissor(r.left, sy, r.width(), r.height()); 403 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 404 } 405 } 406 407 void LayerBase::clearWithOpenGL(const Region& clip) const 408 { 409 clearWithOpenGL(clip,0,0,0,0); 410 } 411 412 void LayerBase::drawWithOpenGL(const Region& clip) const 413 { 414 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 415 const uint32_t fbHeight = hw.getHeight(); 416 const State& s(drawingState()); 417 418 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 419 if (UNLIKELY(s.alpha < 0xFF)) { 420 const GLfloat alpha = s.alpha * (1.0f/255.0f); 421 if (mPremultipliedAlpha) { 422 glColor4f(alpha, alpha, alpha, alpha); 423 } else { 424 glColor4f(1, 1, 1, alpha); 425 } 426 glEnable(GL_BLEND); 427 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 428 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 429 } else { 430 glColor4f(1, 1, 1, 1); 431 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 432 if (!isOpaque()) { 433 glEnable(GL_BLEND); 434 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 435 } else { 436 glDisable(GL_BLEND); 437 } 438 } 439 440 struct TexCoords { 441 GLfloat u; 442 GLfloat v; 443 }; 444 445 TexCoords texCoords[4]; 446 texCoords[0].u = 0; 447 texCoords[0].v = 1; 448 texCoords[1].u = 0; 449 texCoords[1].v = 0; 450 texCoords[2].u = 1; 451 texCoords[2].v = 0; 452 texCoords[3].u = 1; 453 texCoords[3].v = 1; 454 455 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 456 glVertexPointer(2, GL_FLOAT, 0, mVertices); 457 glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 458 459 Region::const_iterator it = clip.begin(); 460 Region::const_iterator const end = clip.end(); 461 while (it != end) { 462 const Rect& r = *it++; 463 const GLint sy = fbHeight - (r.top + r.height()); 464 glScissor(r.left, sy, r.width(), r.height()); 465 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 466 } 467 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 468 glDisable(GL_BLEND); 469 } 470 471 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const 472 { 473 const Layer::State& s(drawingState()); 474 snprintf(buffer, SIZE, 475 "+ %s %p (%s)\n" 476 " " 477 "z=%9d, pos=(%g,%g), size=(%4d,%4d), " 478 "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, " 479 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", 480 getTypeId(), this, getName().string(), 481 s.z, s.transform.tx(), s.transform.ty(), s.w, s.h, 482 isOpaque(), needsDithering(), contentDirty, 483 s.alpha, s.flags, 484 s.transform[0][0], s.transform[0][1], 485 s.transform[1][0], s.transform[1][1]); 486 result.append(buffer); 487 } 488 489 void LayerBase::shortDump(String8& result, char* scratch, size_t size) const 490 { 491 LayerBase::dump(result, scratch, size); 492 } 493 494 495 // --------------------------------------------------------------------------- 496 497 int32_t LayerBaseClient::sIdentity = 1; 498 499 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 500 const sp<Client>& client) 501 : LayerBase(flinger, display), 502 mHasSurface(false), 503 mClientRef(client), 504 mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 505 { 506 } 507 508 LayerBaseClient::~LayerBaseClient() 509 { 510 sp<Client> c(mClientRef.promote()); 511 if (c != 0) { 512 c->detachLayer(this); 513 } 514 } 515 516 sp<ISurface> LayerBaseClient::createSurface() 517 { 518 class BSurface : public BnSurface, public LayerCleaner { 519 virtual sp<ISurfaceTexture> getSurfaceTexture() const { return 0; } 520 public: 521 BSurface(const sp<SurfaceFlinger>& flinger, 522 const sp<LayerBaseClient>& layer) 523 : LayerCleaner(flinger, layer) { } 524 }; 525 sp<ISurface> sur(new BSurface(mFlinger, this)); 526 return sur; 527 } 528 529 sp<ISurface> LayerBaseClient::getSurface() 530 { 531 sp<ISurface> s; 532 Mutex::Autolock _l(mLock); 533 534 LOG_ALWAYS_FATAL_IF(mHasSurface, 535 "LayerBaseClient::getSurface() has already been called"); 536 537 mHasSurface = true; 538 s = createSurface(); 539 mClientSurfaceBinder = s->asBinder(); 540 return s; 541 } 542 543 wp<IBinder> LayerBaseClient::getSurfaceBinder() const { 544 return mClientSurfaceBinder; 545 } 546 547 wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const { 548 return 0; 549 } 550 551 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const 552 { 553 LayerBase::dump(result, buffer, SIZE); 554 555 sp<Client> client(mClientRef.promote()); 556 snprintf(buffer, SIZE, 557 " client=%p, identity=%u\n", 558 client.get(), getIdentity()); 559 560 result.append(buffer); 561 } 562 563 564 void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const 565 { 566 LayerBaseClient::dump(result, scratch, size); 567 } 568 569 // --------------------------------------------------------------------------- 570 571 LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 572 const sp<LayerBaseClient>& layer) 573 : mFlinger(flinger), mLayer(layer) { 574 } 575 576 LayerBaseClient::LayerCleaner::~LayerCleaner() { 577 // destroy client resources 578 mFlinger->destroySurface(mLayer); 579 } 580 581 // --------------------------------------------------------------------------- 582 583 }; // namespace android 584