LayerBase.cpp revision 25e66fc324bbc004fa8902b2d4699e41bb601104
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 36namespace android { 37 38// --------------------------------------------------------------------------- 39 40int32_t LayerBase::sSequence = 1; 41 42LayerBase::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 57LayerBase::~LayerBase() 58{ 59} 60 61void LayerBase::setName(const String8& name) { 62 mName = name; 63} 64 65String8 LayerBase::getName() const { 66 return mName; 67} 68 69const GraphicPlane& LayerBase::graphicPlane(int dpy) const 70{ 71 return mFlinger->graphicPlane(dpy); 72} 73 74GraphicPlane& LayerBase::graphicPlane(int dpy) 75{ 76 return mFlinger->graphicPlane(dpy); 77} 78 79void 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 102void LayerBase::commitTransaction() { 103 mDrawingState = mCurrentState; 104} 105void 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} 111bool LayerBase::requestTransaction() { 112 int32_t old = setTransactionFlags(eTransactionNeeded); 113 return ((old & eTransactionNeeded) == 0); 114} 115uint32_t LayerBase::getTransactionFlags(uint32_t flags) { 116 return android_atomic_and(~flags, &mTransactionFlags) & flags; 117} 118uint32_t LayerBase::setTransactionFlags(uint32_t flags) { 119 return android_atomic_or(flags, &mTransactionFlags); 120} 121 122bool 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} 130bool 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} 138bool 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} 146bool 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} 154bool 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} 161bool LayerBase::setTransparentRegionHint(const Region& transparent) { 162 mCurrentState.sequence++; 163 mCurrentState.transparentRegion = transparent; 164 requestTransaction(); 165 return true; 166} 167bool 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 177Rect LayerBase::visibleBounds() const 178{ 179 return mTransformedBounds; 180} 181 182void LayerBase::setVisibleRegion(const Region& visibleRegion) { 183 // always called from main thread 184 visibleRegionScreen = visibleRegion; 185} 186 187void LayerBase::setCoveredRegion(const Region& coveredRegion) { 188 // always called from main thread 189 coveredRegionScreen = coveredRegion; 190} 191 192uint32_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 226void 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 (CC_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 265void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 266{ 267} 268 269void 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 277void LayerBase::invalidate() 278{ 279 if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 280 mFlinger->signalEvent(); 281 } 282} 283 284void 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 305void 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 344void LayerBase::setPerFrameData(hwc_layer_t* hwcl) { 345 hwcl->compositionType = HWC_FRAMEBUFFER; 346 hwcl->handle = NULL; 347} 348 349void LayerBase::setOverlay(bool inOverlay) { 350 mInOverlay = inOverlay; 351} 352 353bool LayerBase::isOverlay() const { 354 return mInOverlay; 355} 356 357void LayerBase::setFiltering(bool filtering) 358{ 359 mFiltering = filtering; 360} 361 362bool LayerBase::getFiltering() const 363{ 364 return mFiltering; 365} 366 367void LayerBase::draw(const Region& clip) const 368{ 369 // reset GL state 370 glEnable(GL_SCISSOR_TEST); 371 372 onDraw(clip); 373} 374 375void LayerBase::drawForSreenShot() 376{ 377 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 378 setFiltering(true); 379 onDraw( Region(hw.bounds()) ); 380 setFiltering(false); 381} 382 383void 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 407void LayerBase::clearWithOpenGL(const Region& clip) const 408{ 409 clearWithOpenGL(clip,0,0,0,0); 410} 411 412void 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 (CC_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 471void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const 472{ 473 const Layer::State& s(drawingState()); 474 s.transparentRegion.dump(result, "transparentRegion"); 475 transparentRegionScreen.dump(result, "transparentRegionScreen"); 476 visibleRegionScreen.dump(result, "visibleRegionScreen"); 477 snprintf(buffer, SIZE, 478 "+ %s %p (%s)\n" 479 " " 480 "z=%9d, pos=(%g,%g), size=(%4d,%4d), " 481 "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, " 482 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", 483 getTypeId(), this, getName().string(), 484 s.z, s.transform.tx(), s.transform.ty(), s.w, s.h, 485 isOpaque(), needsDithering(), contentDirty, 486 s.alpha, s.flags, 487 s.transform[0][0], s.transform[0][1], 488 s.transform[1][0], s.transform[1][1]); 489 result.append(buffer); 490} 491 492void LayerBase::shortDump(String8& result, char* scratch, size_t size) const { 493 LayerBase::dump(result, scratch, size); 494} 495 496void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const { 497} 498 499void LayerBase::clearStats() { 500} 501 502// --------------------------------------------------------------------------- 503 504int32_t LayerBaseClient::sIdentity = 1; 505 506LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 507 const sp<Client>& client) 508 : LayerBase(flinger, display), 509 mHasSurface(false), 510 mClientRef(client), 511 mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 512{ 513} 514 515LayerBaseClient::~LayerBaseClient() 516{ 517 sp<Client> c(mClientRef.promote()); 518 if (c != 0) { 519 c->detachLayer(this); 520 } 521} 522 523sp<ISurface> LayerBaseClient::createSurface() 524{ 525 class BSurface : public BnSurface, public LayerCleaner { 526 virtual sp<ISurfaceTexture> getSurfaceTexture() const { return 0; } 527 public: 528 BSurface(const sp<SurfaceFlinger>& flinger, 529 const sp<LayerBaseClient>& layer) 530 : LayerCleaner(flinger, layer) { } 531 }; 532 sp<ISurface> sur(new BSurface(mFlinger, this)); 533 return sur; 534} 535 536sp<ISurface> LayerBaseClient::getSurface() 537{ 538 sp<ISurface> s; 539 Mutex::Autolock _l(mLock); 540 541 LOG_ALWAYS_FATAL_IF(mHasSurface, 542 "LayerBaseClient::getSurface() has already been called"); 543 544 mHasSurface = true; 545 s = createSurface(); 546 mClientSurfaceBinder = s->asBinder(); 547 return s; 548} 549 550wp<IBinder> LayerBaseClient::getSurfaceBinder() const { 551 return mClientSurfaceBinder; 552} 553 554wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const { 555 return 0; 556} 557 558void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const 559{ 560 LayerBase::dump(result, buffer, SIZE); 561 562 sp<Client> client(mClientRef.promote()); 563 snprintf(buffer, SIZE, 564 " client=%p, identity=%u\n", 565 client.get(), getIdentity()); 566 567 result.append(buffer); 568} 569 570 571void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const 572{ 573 LayerBaseClient::dump(result, scratch, size); 574} 575 576// --------------------------------------------------------------------------- 577 578LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 579 const sp<LayerBaseClient>& layer) 580 : mFlinger(flinger), mLayer(layer) { 581} 582 583LayerBaseClient::LayerCleaner::~LayerCleaner() { 584 // destroy client resources 585 mFlinger->destroySurface(mLayer); 586} 587 588// --------------------------------------------------------------------------- 589 590}; // namespace android 591