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