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