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