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#define LOG_TAG "SurfaceFlinger" 18 19#include <stdlib.h> 20#include <stdint.h> 21#include <sys/types.h> 22 23#include <utils/Errors.h> 24#include <utils/Log.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 "LayerBlur.h" 34#include "SurfaceFlinger.h" 35#include "DisplayHardware/DisplayHardware.h" 36 37 38// We don't honor the premultiplied alpha flags, which means that 39// premultiplied surface may be composed using a non-premultiplied 40// equation. We do this because it may be a lot faster on some hardware 41// The correct value is HONOR_PREMULTIPLIED_ALPHA = 1 42#define HONOR_PREMULTIPLIED_ALPHA 0 43 44namespace android { 45 46// --------------------------------------------------------------------------- 47 48const uint32_t LayerBase::typeInfo = 1; 49const char* const LayerBase::typeID = "LayerBase"; 50 51const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2; 52const char* const LayerBaseClient::typeID = "LayerBaseClient"; 53 54// --------------------------------------------------------------------------- 55 56Vector<GLuint> LayerBase::deletedTextures; 57 58int32_t LayerBase::sIdentity = 0; 59 60LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) 61 : dpy(display), contentDirty(false), 62 mFlinger(flinger), 63 mTransformed(false), 64 mOrientation(0), 65 mCanUseCopyBit(false), 66 mTransactionFlags(0), 67 mPremultipliedAlpha(true), 68 mIdentity(uint32_t(android_atomic_inc(&sIdentity))), 69 mInvalidate(0) 70{ 71 const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); 72 mFlags = hw.getFlags(); 73} 74 75LayerBase::~LayerBase() 76{ 77} 78 79const GraphicPlane& LayerBase::graphicPlane(int dpy) const 80{ 81 return mFlinger->graphicPlane(dpy); 82} 83 84GraphicPlane& LayerBase::graphicPlane(int dpy) 85{ 86 return mFlinger->graphicPlane(dpy); 87} 88 89void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) 90{ 91 uint32_t layerFlags = 0; 92 if (flags & ISurfaceComposer::eHidden) 93 layerFlags = ISurfaceComposer::eLayerHidden; 94 95 if (flags & ISurfaceComposer::eNonPremultiplied) 96 mPremultipliedAlpha = false; 97 98 mCurrentState.z = 0; 99 mCurrentState.w = w; 100 mCurrentState.h = h; 101 mCurrentState.alpha = 0xFF; 102 mCurrentState.flags = layerFlags; 103 mCurrentState.sequence = 0; 104 mCurrentState.transform.set(0, 0); 105 106 // drawing state & current state are identical 107 mDrawingState = mCurrentState; 108} 109 110void LayerBase::commitTransaction(bool skipSize) { 111 const uint32_t w = mDrawingState.w; 112 const uint32_t h = mDrawingState.h; 113 mDrawingState = mCurrentState; 114 if (skipSize) { 115 mDrawingState.w = w; 116 mDrawingState.h = h; 117 } 118} 119void LayerBase::forceVisibilityTransaction() { 120 // this can be called without SurfaceFlinger.mStateLock, but if we 121 // can atomically increment the sequence number, it doesn't matter. 122 android_atomic_inc(&mCurrentState.sequence); 123 requestTransaction(); 124} 125bool LayerBase::requestTransaction() { 126 int32_t old = setTransactionFlags(eTransactionNeeded); 127 return ((old & eTransactionNeeded) == 0); 128} 129uint32_t LayerBase::getTransactionFlags(uint32_t flags) { 130 return android_atomic_and(~flags, &mTransactionFlags) & flags; 131} 132uint32_t LayerBase::setTransactionFlags(uint32_t flags) { 133 return android_atomic_or(flags, &mTransactionFlags); 134} 135 136void LayerBase::setSizeChanged(uint32_t w, uint32_t h) { 137} 138 139bool LayerBase::setPosition(int32_t x, int32_t y) { 140 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 141 return false; 142 mCurrentState.sequence++; 143 mCurrentState.transform.set(x, y); 144 requestTransaction(); 145 return true; 146} 147bool LayerBase::setLayer(uint32_t z) { 148 if (mCurrentState.z == z) 149 return false; 150 mCurrentState.sequence++; 151 mCurrentState.z = z; 152 requestTransaction(); 153 return true; 154} 155bool LayerBase::setSize(uint32_t w, uint32_t h) { 156 if (mCurrentState.w == w && mCurrentState.h == h) 157 return false; 158 setSizeChanged(w, h); 159 mCurrentState.w = w; 160 mCurrentState.h = h; 161 requestTransaction(); 162 return true; 163} 164bool LayerBase::setAlpha(uint8_t alpha) { 165 if (mCurrentState.alpha == alpha) 166 return false; 167 mCurrentState.sequence++; 168 mCurrentState.alpha = alpha; 169 requestTransaction(); 170 return true; 171} 172bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) { 173 // TODO: check the matrix has changed 174 mCurrentState.sequence++; 175 mCurrentState.transform.set( 176 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 177 requestTransaction(); 178 return true; 179} 180bool LayerBase::setTransparentRegionHint(const Region& transparent) { 181 // TODO: check the region has changed 182 mCurrentState.sequence++; 183 mCurrentState.transparentRegion = transparent; 184 requestTransaction(); 185 return true; 186} 187bool LayerBase::setFlags(uint8_t flags, uint8_t mask) { 188 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 189 if (mCurrentState.flags == newFlags) 190 return false; 191 mCurrentState.sequence++; 192 mCurrentState.flags = newFlags; 193 requestTransaction(); 194 return true; 195} 196 197Rect LayerBase::visibleBounds() const 198{ 199 return mTransformedBounds; 200} 201 202void LayerBase::setVisibleRegion(const Region& visibleRegion) { 203 // always called from main thread 204 visibleRegionScreen = visibleRegion; 205} 206 207void LayerBase::setCoveredRegion(const Region& coveredRegion) { 208 // always called from main thread 209 coveredRegionScreen = coveredRegion; 210} 211 212uint32_t LayerBase::doTransaction(uint32_t flags) 213{ 214 const Layer::State& front(drawingState()); 215 const Layer::State& temp(currentState()); 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 223 // Commit the transaction 224 commitTransaction(flags & eRestartTransaction); 225 return flags; 226} 227 228Point LayerBase::getPhysicalSize() const 229{ 230 const Layer::State& front(drawingState()); 231 return Point(front.w, front.h); 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 const Point size(getPhysicalSize()); 241 uint32_t w = size.x; 242 uint32_t h = size.y; 243 tr.transform(mVertices[0], 0, 0); 244 tr.transform(mVertices[1], 0, h); 245 tr.transform(mVertices[2], w, h); 246 tr.transform(mVertices[3], w, 0); 247 if (UNLIKELY(transformed)) { 248 // NOTE: here we could also punt if we have too many rectangles 249 // in the transparent region 250 if (tr.preserveRects()) { 251 // transform the transparent region 252 transparentRegionScreen = tr.transform(s.transparentRegion); 253 } else { 254 // transformation too complex, can't do the transparent region 255 // optimization. 256 transparentRegionScreen.clear(); 257 } 258 } else { 259 transparentRegionScreen = s.transparentRegion; 260 } 261 262 // cache a few things... 263 mOrientation = tr.getOrientation(); 264 mTransformedBounds = tr.makeBounds(w, h); 265 mTransformed = transformed; 266 mLeft = tr.tx(); 267 mTop = tr.ty(); 268 269 // see if we can/should use 2D h/w with the new configuration 270 mCanUseCopyBit = false; 271 copybit_device_t* copybit = mFlinger->getBlitEngine(); 272 if (copybit) { 273 const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG); 274 const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS); 275 mCanUseCopyBit = true; 276 if ((mOrientation < 0) && (step > 1)) { 277 // arbitrary orientations not supported 278 mCanUseCopyBit = false; 279 } else if ((mOrientation > 0) && (step > 90)) { 280 // 90 deg rotations not supported 281 mCanUseCopyBit = false; 282 } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { 283 // arbitrary scaling not supported 284 mCanUseCopyBit = false; 285 } 286#if HONOR_PREMULTIPLIED_ALPHA 287 else if (needsBlending() && mPremultipliedAlpha) { 288 // pre-multiplied alpha not supported 289 mCanUseCopyBit = false; 290 } 291#endif 292 else { 293 // here, we determined we can use copybit 294 if (tr.getType() & SkMatrix::kScale_Mask) { 295 // and we have scaling 296 if (!transparentRegionScreen.isRect()) { 297 // we punt because blending is cheap (h/w) and the region is 298 // complex, which may causes artifacts when copying 299 // scaled content 300 transparentRegionScreen.clear(); 301 } 302 } 303 } 304 } 305} 306 307void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 308{ 309} 310 311void LayerBase::unlockPageFlip( 312 const Transform& planeTransform, Region& outDirtyRegion) 313{ 314 if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { 315 outDirtyRegion.orSelf(visibleRegionScreen); 316 } 317} 318 319void LayerBase::finishPageFlip() 320{ 321} 322 323void LayerBase::invalidate() 324{ 325 if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 326 mFlinger->signalEvent(); 327 } 328} 329 330void LayerBase::drawRegion(const Region& reg) const 331{ 332 Region::iterator iterator(reg); 333 if (iterator) { 334 Rect r; 335 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 336 const int32_t fbWidth = hw.getWidth(); 337 const int32_t fbHeight = hw.getHeight(); 338 const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 339 { fbWidth, fbHeight }, { 0, fbHeight } }; 340 glVertexPointer(2, GL_SHORT, 0, vertices); 341 while (iterator.iterate(&r)) { 342 const GLint sy = fbHeight - (r.top + r.height()); 343 glScissor(r.left, sy, r.width(), r.height()); 344 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 345 } 346 } 347} 348 349void LayerBase::draw(const Region& inClip) const 350{ 351 // invalidate the region we'll update 352 Region clip(inClip); // copy-on-write, so no-op most of the time 353 354 // Remove the transparent area from the clipping region 355 const State& s = drawingState(); 356 if (LIKELY(!s.transparentRegion.isEmpty())) { 357 clip.subtract(transparentRegionScreen); 358 if (clip.isEmpty()) { 359 // usually this won't happen because this should be taken care of 360 // by SurfaceFlinger::computeVisibleRegions() 361 return; 362 } 363 } 364 365 // reset GL state 366 glEnable(GL_SCISSOR_TEST); 367 368 onDraw(clip); 369 370 /* 371 glDisable(GL_TEXTURE_2D); 372 glDisable(GL_DITHER); 373 glEnable(GL_BLEND); 374 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 375 glColor4x(0, 0x8000, 0, 0x10000); 376 drawRegion(transparentRegionScreen); 377 glDisable(GL_BLEND); 378 */ 379} 380 381GLuint LayerBase::createTexture() const 382{ 383 GLuint textureName = -1; 384 glGenTextures(1, &textureName); 385 glBindTexture(GL_TEXTURE_2D, textureName); 386 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 387 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 388 if (mFlags & DisplayHardware::SLOW_CONFIG) { 389 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 390 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 391 } else { 392 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 393 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 394 } 395 return textureName; 396} 397 398void LayerBase::clearWithOpenGL(const Region& clip) const 399{ 400 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 401 const uint32_t fbHeight = hw.getHeight(); 402 glColor4x(0,0,0,0); 403 glDisable(GL_TEXTURE_2D); 404 glDisable(GL_BLEND); 405 glDisable(GL_DITHER); 406 Rect r; 407 Region::iterator iterator(clip); 408 if (iterator) { 409 glEnable(GL_SCISSOR_TEST); 410 glVertexPointer(2, GL_FIXED, 0, mVertices); 411 while (iterator.iterate(&r)) { 412 const GLint sy = fbHeight - (r.top + r.height()); 413 glScissor(r.left, sy, r.width(), r.height()); 414 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 415 } 416 } 417} 418 419void LayerBase::drawWithOpenGL(const Region& clip, 420 GLint textureName, const GGLSurface& t, int transform) const 421{ 422 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 423 const uint32_t fbHeight = hw.getHeight(); 424 const State& s(drawingState()); 425 426 // bind our texture 427 validateTexture(textureName); 428 glEnable(GL_TEXTURE_2D); 429 430 // Dithering... 431 if (s.flags & ISurfaceComposer::eLayerDither) { 432 glEnable(GL_DITHER); 433 } else { 434 glDisable(GL_DITHER); 435 } 436 437 if (UNLIKELY(s.alpha < 0xFF)) { 438 // We have an alpha-modulation. We need to modulate all 439 // texture components by alpha because we're always using 440 // premultiplied alpha. 441 442 // If the texture doesn't have an alpha channel we can 443 // use REPLACE and switch to non premultiplied alpha 444 // blending (SRCA/ONE_MINUS_SRCA). 445 446 GLenum env, src; 447 if (needsBlending()) { 448 env = GL_MODULATE; 449 src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 450 } else { 451 env = GL_REPLACE; 452 src = GL_SRC_ALPHA; 453 } 454 const GGLfixed alpha = (s.alpha << 16)/255; 455 glColor4x(alpha, alpha, alpha, alpha); 456 glEnable(GL_BLEND); 457 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 458 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); 459 } else { 460 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 461 glColor4x(0x10000, 0x10000, 0x10000, 0x10000); 462 if (needsBlending()) { 463 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 464 glEnable(GL_BLEND); 465 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 466 } else { 467 glDisable(GL_BLEND); 468 } 469 } 470 471 if (UNLIKELY(transformed() 472 || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 473 { 474 //StopWatch watch("GL transformed"); 475 Region::iterator iterator(clip); 476 if (iterator) { 477 // always use high-quality filtering with fast configurations 478 bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG); 479 if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { 480 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 481 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 482 } 483 const GLfixed texCoords[4][2] = { 484 { 0, 0 }, 485 { 0, 0x10000 }, 486 { 0x10000, 0x10000 }, 487 { 0x10000, 0 } 488 }; 489 490 glMatrixMode(GL_TEXTURE); 491 glLoadIdentity(); 492 493 if (transform == HAL_TRANSFORM_ROT_90) { 494 glTranslatef(0, 1, 0); 495 glRotatef(-90, 0, 0, 1); 496 } 497 498 if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { 499 // find the smallest power-of-two that will accommodate our surface 500 GLuint tw = 1 << (31 - clz(t.width)); 501 GLuint th = 1 << (31 - clz(t.height)); 502 if (tw < t.width) tw <<= 1; 503 if (th < t.height) th <<= 1; 504 // this divide should be relatively fast because it's 505 // a power-of-two (optimized path in libgcc) 506 GLfloat ws = GLfloat(t.width) /tw; 507 GLfloat hs = GLfloat(t.height)/th; 508 glScalef(ws, hs, 1.0f); 509 } 510 511 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 512 glVertexPointer(2, GL_FIXED, 0, mVertices); 513 glTexCoordPointer(2, GL_FIXED, 0, texCoords); 514 515 Rect r; 516 while (iterator.iterate(&r)) { 517 const GLint sy = fbHeight - (r.top + r.height()); 518 glScissor(r.left, sy, r.width(), r.height()); 519 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 520 } 521 522 if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { 523 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 524 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 525 } 526 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 527 } 528 } else { 529 Region::iterator iterator(clip); 530 if (iterator) { 531 Rect r; 532 GLint crop[4] = { 0, t.height, t.width, -t.height }; 533 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); 534 int x = tx(); 535 int y = ty(); 536 y = fbHeight - (y + t.height); 537 while (iterator.iterate(&r)) { 538 const GLint sy = fbHeight - (r.top + r.height()); 539 glScissor(r.left, sy, r.width(), r.height()); 540 glDrawTexiOES(x, y, 0, t.width, t.height); 541 } 542 } 543 } 544} 545 546void LayerBase::validateTexture(GLint textureName) const 547{ 548 glBindTexture(GL_TEXTURE_2D, textureName); 549 // TODO: reload the texture if needed 550 // this is currently done in loadTexture() below 551} 552 553void LayerBase::loadTexture(const Region& dirty, 554 GLint textureName, const GGLSurface& t, 555 GLuint& textureWidth, GLuint& textureHeight) const 556{ 557 // TODO: defer the actual texture reload until LayerBase::validateTexture 558 // is called. 559 560 uint32_t flags = mFlags; 561 glBindTexture(GL_TEXTURE_2D, textureName); 562 563 GLuint tw = t.width; 564 GLuint th = t.height; 565 566 /* 567 * In OpenGL ES we can't specify a stride with glTexImage2D (however, 568 * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of 569 * stride). 570 * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we 571 * need to do something reasonable (here creating a bigger texture). 572 * 573 * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT); 574 * 575 * This situation doesn't happen often, but some h/w have a limitation 576 * for their framebuffer (eg: must be multiple of 8 pixels), and 577 * we need to take that into account when using these buffers as 578 * textures. 579 * 580 * This should never be a problem with POT textures 581 */ 582 583 tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4); 584 585 /* 586 * round to POT if needed 587 */ 588 589 GLuint texture_w = tw; 590 GLuint texture_h = th; 591 if (!(flags & DisplayHardware::NPOT_EXTENSION)) { 592 // find the smallest power-of-two that will accommodate our surface 593 texture_w = 1 << (31 - clz(t.width)); 594 texture_h = 1 << (31 - clz(t.height)); 595 if (texture_w < t.width) texture_w <<= 1; 596 if (texture_h < t.height) texture_h <<= 1; 597 if (texture_w != tw || texture_h != th) { 598 // we can't use DIRECT_TEXTURE since we changed the size 599 // of the texture 600 flags &= ~DisplayHardware::DIRECT_TEXTURE; 601 } 602 } 603 604 if (flags & DisplayHardware::DIRECT_TEXTURE) { 605 // here we're guaranteed that texture_{w|h} == t{w|h} 606 if (t.format == GGL_PIXEL_FORMAT_RGB_565) { 607 glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0, 608 GL_RGB, tw, th, 0, 609 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data); 610 } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { 611 glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0, 612 GL_RGBA, tw, th, 0, 613 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data); 614 } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { 615 glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0, 616 GL_RGBA, tw, th, 0, 617 GL_RGBA, GL_UNSIGNED_BYTE, t.data); 618 } else if (t.format == GGL_PIXEL_FORMAT_BGRA_8888) { 619 // TODO: add GL_BGRA extension 620 } else { 621 // oops, we don't handle this format, try the regular path 622 goto regular; 623 } 624 textureWidth = tw; 625 textureHeight = th; 626 } else { 627regular: 628 Rect bounds(dirty.bounds()); 629 GLvoid* data = 0; 630 if (texture_w!=textureWidth || texture_h!=textureHeight) { 631 // texture size changed, we need to create a new one 632 633 if (!textureWidth || !textureHeight) { 634 // this is the first time, load the whole texture 635 if (texture_w==tw && texture_h==th) { 636 // we can do it one pass 637 data = t.data; 638 } else { 639 // we have to create the texture first because it 640 // doesn't match the size of the buffer 641 bounds.set(Rect(tw, th)); 642 } 643 } 644 645 if (t.format == GGL_PIXEL_FORMAT_RGB_565) { 646 glTexImage2D(GL_TEXTURE_2D, 0, 647 GL_RGB, texture_w, texture_h, 0, 648 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); 649 } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { 650 glTexImage2D(GL_TEXTURE_2D, 0, 651 GL_RGBA, texture_w, texture_h, 0, 652 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); 653 } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { 654 glTexImage2D(GL_TEXTURE_2D, 0, 655 GL_RGBA, texture_w, texture_h, 0, 656 GL_RGBA, GL_UNSIGNED_BYTE, data); 657 } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP || 658 t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) { 659 // just show the Y plane of YUV buffers 660 data = t.data; 661 glTexImage2D(GL_TEXTURE_2D, 0, 662 GL_LUMINANCE, texture_w, texture_h, 0, 663 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 664 } else { 665 // oops, we don't handle this format! 666 LOGE("layer %p, texture=%d, using format %d, which is not " 667 "supported by the GL", this, textureName, t.format); 668 textureName = -1; 669 } 670 textureWidth = texture_w; 671 textureHeight = texture_h; 672 } 673 if (!data && textureName>=0) { 674 if (t.format == GGL_PIXEL_FORMAT_RGB_565) { 675 glTexSubImage2D(GL_TEXTURE_2D, 0, 676 0, bounds.top, t.width, bounds.height(), 677 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 678 t.data + bounds.top*t.width*2); 679 } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { 680 glTexSubImage2D(GL_TEXTURE_2D, 0, 681 0, bounds.top, t.width, bounds.height(), 682 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 683 t.data + bounds.top*t.width*2); 684 } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) { 685 glTexSubImage2D(GL_TEXTURE_2D, 0, 686 0, bounds.top, t.width, bounds.height(), 687 GL_RGBA, GL_UNSIGNED_BYTE, 688 t.data + bounds.top*t.width*4); 689 } 690 } 691 } 692} 693 694bool LayerBase::canUseCopybit() const 695{ 696 return mCanUseCopyBit; 697} 698 699// --------------------------------------------------------------------------- 700 701LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 702 Client* c, int32_t i) 703 : LayerBase(flinger, display), client(c), 704 lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ), 705 mIndex(i) 706{ 707 if (client) { 708 client->bindLayer(this, i); 709 710 // Initialize this layer's control block 711 memset(this->lcblk, 0, sizeof(layer_cblk_t)); 712 this->lcblk->identity = mIdentity; 713 Region::writeEmpty(&(this->lcblk->region[0]), sizeof(flat_region_t)); 714 Region::writeEmpty(&(this->lcblk->region[1]), sizeof(flat_region_t)); 715 } 716} 717 718LayerBaseClient::~LayerBaseClient() 719{ 720 if (client) { 721 client->free(mIndex); 722 } 723} 724 725int32_t LayerBaseClient::serverIndex() const { 726 if (client) { 727 return (client->cid<<16)|mIndex; 728 } 729 return 0xFFFF0000 | mIndex; 730} 731 732sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const 733{ 734 return new Surface(clientIndex(), mIdentity); 735} 736 737 738// --------------------------------------------------------------------------- 739 740}; // namespace android 741