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 ATRACE_TAG ATRACE_TAG_GRAPHICS
18
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <sys/types.h>
22 #include <math.h>
23
24 #include <cutils/compiler.h>
25 #include <cutils/native_handle.h>
26 #include <cutils/properties.h>
27
28 #include <utils/Errors.h>
29 #include <utils/Log.h>
30 #include <utils/StopWatch.h>
31 #include <utils/Trace.h>
32
33 #include <ui/GraphicBuffer.h>
34 #include <ui/PixelFormat.h>
35
36 #include <gui/Surface.h>
37
38 #include "clz.h"
39 #include "DisplayHardware/DisplayHardware.h"
40 #include "DisplayHardware/HWComposer.h"
41 #include "GLExtensions.h"
42 #include "Layer.h"
43 #include "SurfaceFlinger.h"
44 #include "SurfaceTextureLayer.h"
45
46 #define DEBUG_RESIZE 0
47
48 namespace android {
49
50 // ---------------------------------------------------------------------------
51
Layer(SurfaceFlinger * flinger,DisplayID display,const sp<Client> & client)52 Layer::Layer(SurfaceFlinger* flinger,
53 DisplayID display, const sp<Client>& client)
54 : LayerBaseClient(flinger, display, client),
55 mTextureName(-1U),
56 mQueuedFrames(0),
57 mCurrentTransform(0),
58 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
59 mCurrentOpacity(true),
60 mRefreshPending(false),
61 mFrameLatencyNeeded(false),
62 mFrameLatencyOffset(0),
63 mFormat(PIXEL_FORMAT_NONE),
64 mGLExtensions(GLExtensions::getInstance()),
65 mOpaqueLayer(true),
66 mNeedsDithering(false),
67 mSecure(false),
68 mProtectedByApp(false)
69 {
70 mCurrentCrop.makeInvalid();
71 glGenTextures(1, &mTextureName);
72 }
73
onLayerDisplayed()74 void Layer::onLayerDisplayed() {
75 if (mFrameLatencyNeeded) {
76 const DisplayHardware& hw(graphicPlane(0).displayHardware());
77 mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
78 mFrameStats[mFrameLatencyOffset].set = systemTime();
79 mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
80 mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
81 mFrameLatencyNeeded = false;
82 }
83 }
84
onFirstRef()85 void Layer::onFirstRef()
86 {
87 LayerBaseClient::onFirstRef();
88
89 struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
90 FrameQueuedListener(Layer* layer) : mLayer(layer) { }
91 private:
92 wp<Layer> mLayer;
93 virtual void onFrameAvailable() {
94 sp<Layer> that(mLayer.promote());
95 if (that != 0) {
96 that->onFrameQueued();
97 }
98 }
99 };
100
101 // Creates a custom BufferQueue for SurfaceTexture to use
102 sp<BufferQueue> bq = new SurfaceTextureLayer();
103 mSurfaceTexture = new SurfaceTexture(mTextureName, true,
104 GL_TEXTURE_EXTERNAL_OES, false, bq);
105
106 mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
107 mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
108 mSurfaceTexture->setSynchronousMode(true);
109
110 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
111 #warning "disabling triple buffering"
112 mSurfaceTexture->setBufferCountServer(2);
113 #else
114 mSurfaceTexture->setBufferCountServer(3);
115 #endif
116 }
117
~Layer()118 Layer::~Layer()
119 {
120 mFlinger->postMessageAsync(
121 new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
122 }
123
onFrameQueued()124 void Layer::onFrameQueued() {
125 android_atomic_inc(&mQueuedFrames);
126 mFlinger->signalLayerUpdate();
127 }
128
129 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
130 // in the purgatory list
onRemoved()131 void Layer::onRemoved()
132 {
133 mSurfaceTexture->abandon();
134 }
135
setName(const String8 & name)136 void Layer::setName(const String8& name) {
137 LayerBase::setName(name);
138 mSurfaceTexture->setName(name);
139 }
140
validateVisibility(const Transform & globalTransform)141 void Layer::validateVisibility(const Transform& globalTransform) {
142 LayerBase::validateVisibility(globalTransform);
143
144 // This optimization allows the SurfaceTexture to bake in
145 // the rotation so hardware overlays can be used
146 mSurfaceTexture->setTransformHint(getTransformHint());
147 }
148
createSurface()149 sp<ISurface> Layer::createSurface()
150 {
151 class BSurface : public BnSurface, public LayerCleaner {
152 wp<const Layer> mOwner;
153 virtual sp<ISurfaceTexture> getSurfaceTexture() const {
154 sp<ISurfaceTexture> res;
155 sp<const Layer> that( mOwner.promote() );
156 if (that != NULL) {
157 res = that->mSurfaceTexture->getBufferQueue();
158 }
159 return res;
160 }
161 public:
162 BSurface(const sp<SurfaceFlinger>& flinger,
163 const sp<Layer>& layer)
164 : LayerCleaner(flinger, layer), mOwner(layer) { }
165 };
166 sp<ISurface> sur(new BSurface(mFlinger, this));
167 return sur;
168 }
169
getSurfaceTextureBinder() const170 wp<IBinder> Layer::getSurfaceTextureBinder() const
171 {
172 return mSurfaceTexture->getBufferQueue()->asBinder();
173 }
174
setBuffers(uint32_t w,uint32_t h,PixelFormat format,uint32_t flags)175 status_t Layer::setBuffers( uint32_t w, uint32_t h,
176 PixelFormat format, uint32_t flags)
177 {
178 // this surfaces pixel format
179 PixelFormatInfo info;
180 status_t err = getPixelFormatInfo(format, &info);
181 if (err) {
182 ALOGE("unsupported pixelformat %d", format);
183 return err;
184 }
185
186 // the display's pixel format
187 const DisplayHardware& hw(graphicPlane(0).displayHardware());
188 uint32_t const maxSurfaceDims = min(
189 hw.getMaxTextureSize(), hw.getMaxViewportDims());
190
191 // never allow a surface larger than what our underlying GL implementation
192 // can handle.
193 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
194 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
195 return BAD_VALUE;
196 }
197
198 PixelFormatInfo displayInfo;
199 getPixelFormatInfo(hw.getFormat(), &displayInfo);
200 const uint32_t hwFlags = hw.getFlags();
201
202 mFormat = format;
203
204 mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
205 mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
206 mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
207 mCurrentOpacity = getOpacityForFormat(format);
208
209 mSurfaceTexture->setDefaultBufferSize(w, h);
210 mSurfaceTexture->setDefaultBufferFormat(format);
211 mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
212
213 // we use the red index
214 int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
215 int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
216 mNeedsDithering = layerRedsize > displayRedSize;
217
218 return NO_ERROR;
219 }
220
computeBufferCrop() const221 Rect Layer::computeBufferCrop() const {
222 // Start with the SurfaceTexture's buffer crop...
223 Rect crop;
224 if (!mCurrentCrop.isEmpty()) {
225 crop = mCurrentCrop;
226 } else if (mActiveBuffer != NULL){
227 crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
228 } else {
229 crop = Rect(mTransformedBounds.width(), mTransformedBounds.height());
230 }
231
232 // ... then reduce that in the same proportions as the window crop reduces
233 // the window size.
234 const State& s(drawingState());
235 if (!s.active.crop.isEmpty()) {
236 // Transform the window crop to match the buffer coordinate system,
237 // which means using the inverse of the current transform set on the
238 // SurfaceTexture.
239 uint32_t invTransform = mCurrentTransform;
240 int winWidth = s.active.w;
241 int winHeight = s.active.h;
242 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
243 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
244 NATIVE_WINDOW_TRANSFORM_FLIP_H;
245 winWidth = s.active.h;
246 winHeight = s.active.w;
247 }
248 Rect winCrop = s.active.crop.transform(invTransform,
249 s.active.w, s.active.h);
250
251 float xScale = float(crop.width()) / float(winWidth);
252 float yScale = float(crop.height()) / float(winHeight);
253 crop.left += int(ceilf(float(winCrop.left) * xScale));
254 crop.top += int(ceilf(float(winCrop.top) * yScale));
255 crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
256 crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
257 }
258
259 return crop;
260 }
261
setGeometry(hwc_layer_t * hwcl)262 void Layer::setGeometry(hwc_layer_t* hwcl)
263 {
264 LayerBaseClient::setGeometry(hwcl);
265
266 hwcl->flags &= ~HWC_SKIP_LAYER;
267
268 // we can't do alpha-fade with the hwc HAL
269 const State& s(drawingState());
270 if (s.alpha < 0xFF) {
271 hwcl->flags = HWC_SKIP_LAYER;
272 }
273
274 /*
275 * Transformations are applied in this order:
276 * 1) buffer orientation/flip/mirror
277 * 2) state transformation (window manager)
278 * 3) layer orientation (screen orientation)
279 * mTransform is already the composition of (2) and (3)
280 * (NOTE: the matrices are multiplied in reverse order)
281 */
282
283 const Transform bufferOrientation(mCurrentTransform);
284 const Transform tr(mTransform * bufferOrientation);
285
286 // this gives us only the "orientation" component of the transform
287 const uint32_t finalTransform = tr.getOrientation();
288
289 // we can only handle simple transformation
290 if (finalTransform & Transform::ROT_INVALID) {
291 hwcl->flags = HWC_SKIP_LAYER;
292 } else {
293 hwcl->transform = finalTransform;
294 }
295
296 Rect crop = computeBufferCrop();
297 hwcl->sourceCrop.left = crop.left;
298 hwcl->sourceCrop.top = crop.top;
299 hwcl->sourceCrop.right = crop.right;
300 hwcl->sourceCrop.bottom = crop.bottom;
301 }
302
setPerFrameData(hwc_layer_t * hwcl)303 void Layer::setPerFrameData(hwc_layer_t* hwcl) {
304 const sp<GraphicBuffer>& buffer(mActiveBuffer);
305 if (buffer == NULL) {
306 // this can happen if the client never drew into this layer yet,
307 // or if we ran out of memory. In that case, don't let
308 // HWC handle it.
309 hwcl->flags |= HWC_SKIP_LAYER;
310 hwcl->handle = NULL;
311 } else {
312 hwcl->handle = buffer->handle;
313 }
314 }
315
onDraw(const Region & clip) const316 void Layer::onDraw(const Region& clip) const
317 {
318 ATRACE_CALL();
319
320 if (CC_UNLIKELY(mActiveBuffer == 0)) {
321 // the texture has not been created yet, this Layer has
322 // in fact never been drawn into. This happens frequently with
323 // SurfaceView because the WindowManager can't know when the client
324 // has drawn the first time.
325
326 // If there is nothing under us, we paint the screen in black, otherwise
327 // we just skip this update.
328
329 // figure out if there is something below us
330 Region under;
331 const SurfaceFlinger::LayerVector& drawingLayers(
332 mFlinger->mDrawingState.layersSortedByZ);
333 const size_t count = drawingLayers.size();
334 for (size_t i=0 ; i<count ; ++i) {
335 const sp<LayerBase>& layer(drawingLayers[i]);
336 if (layer.get() == static_cast<LayerBase const*>(this))
337 break;
338 under.orSelf(layer->visibleRegionScreen);
339 }
340 // if not everything below us is covered, we plug the holes!
341 Region holes(clip.subtract(under));
342 if (!holes.isEmpty()) {
343 clearWithOpenGL(holes, 0, 0, 0, 1);
344 }
345 return;
346 }
347
348 if (!isProtected()) {
349 // TODO: we could be more subtle with isFixedSize()
350 const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
351
352 // Query the texture matrix given our current filtering mode.
353 float textureMatrix[16];
354 mSurfaceTexture->setFilteringEnabled(useFiltering);
355 mSurfaceTexture->getTransformMatrix(textureMatrix);
356
357 // Set things up for texturing.
358 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
359 GLenum filter = GL_NEAREST;
360 if (useFiltering) {
361 filter = GL_LINEAR;
362 }
363 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
364 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
365 glMatrixMode(GL_TEXTURE);
366 glLoadMatrixf(textureMatrix);
367 glMatrixMode(GL_MODELVIEW);
368 glDisable(GL_TEXTURE_2D);
369 glEnable(GL_TEXTURE_EXTERNAL_OES);
370 } else {
371 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
372 glMatrixMode(GL_TEXTURE);
373 glLoadIdentity();
374 glMatrixMode(GL_MODELVIEW);
375 glDisable(GL_TEXTURE_EXTERNAL_OES);
376 glEnable(GL_TEXTURE_2D);
377 }
378
379 drawWithOpenGL(clip);
380
381 glDisable(GL_TEXTURE_EXTERNAL_OES);
382 glDisable(GL_TEXTURE_2D);
383 }
384
385 // As documented in libhardware header, formats in the range
386 // 0x100 - 0x1FF are specific to the HAL implementation, and
387 // are known to have no alpha channel
388 // TODO: move definition for device-specific range into
389 // hardware.h, instead of using hard-coded values here.
390 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
391
getOpacityForFormat(uint32_t format)392 bool Layer::getOpacityForFormat(uint32_t format)
393 {
394 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
395 return true;
396 }
397 PixelFormatInfo info;
398 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
399 // in case of error (unknown format), we assume no blending
400 return (err || info.h_alpha <= info.l_alpha);
401 }
402
403
isOpaque() const404 bool Layer::isOpaque() const
405 {
406 // if we don't have a buffer yet, we're translucent regardless of the
407 // layer's opaque flag.
408 if (mActiveBuffer == 0) {
409 return false;
410 }
411
412 // if the layer has the opaque flag, then we're always opaque,
413 // otherwise we use the current buffer's format.
414 return mOpaqueLayer || mCurrentOpacity;
415 }
416
isProtected() const417 bool Layer::isProtected() const
418 {
419 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
420 return (activeBuffer != 0) &&
421 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
422 }
423
doTransaction(uint32_t flags)424 uint32_t Layer::doTransaction(uint32_t flags)
425 {
426 ATRACE_CALL();
427
428 const Layer::State& front(drawingState());
429 const Layer::State& temp(currentState());
430
431 const bool sizeChanged = (temp.requested.w != front.requested.w) ||
432 (temp.requested.h != front.requested.h);
433
434 if (sizeChanged) {
435 // the size changed, we need to ask our client to request a new buffer
436 ALOGD_IF(DEBUG_RESIZE,
437 "doTransaction: geometry (layer=%p), scalingMode=%d\n"
438 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
439 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
440 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
441 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
442 this, mCurrentScalingMode,
443 temp.active.w, temp.active.h,
444 temp.active.crop.left,
445 temp.active.crop.top,
446 temp.active.crop.right,
447 temp.active.crop.bottom,
448 temp.active.crop.getWidth(),
449 temp.active.crop.getHeight(),
450 temp.requested.w, temp.requested.h,
451 temp.requested.crop.left,
452 temp.requested.crop.top,
453 temp.requested.crop.right,
454 temp.requested.crop.bottom,
455 temp.requested.crop.getWidth(),
456 temp.requested.crop.getHeight(),
457 front.active.w, front.active.h,
458 front.active.crop.left,
459 front.active.crop.top,
460 front.active.crop.right,
461 front.active.crop.bottom,
462 front.active.crop.getWidth(),
463 front.active.crop.getHeight(),
464 front.requested.w, front.requested.h,
465 front.requested.crop.left,
466 front.requested.crop.top,
467 front.requested.crop.right,
468 front.requested.crop.bottom,
469 front.requested.crop.getWidth(),
470 front.requested.crop.getHeight());
471
472 // record the new size, form this point on, when the client request
473 // a buffer, it'll get the new size.
474 mSurfaceTexture->setDefaultBufferSize(
475 temp.requested.w, temp.requested.h);
476 }
477
478 if (!isFixedSize()) {
479
480 const bool resizePending = (temp.requested.w != temp.active.w) ||
481 (temp.requested.h != temp.active.h);
482
483 if (resizePending) {
484 // don't let LayerBase::doTransaction update the drawing state
485 // if we have a pending resize, unless we are in fixed-size mode.
486 // the drawing state will be updated only once we receive a buffer
487 // with the correct size.
488 //
489 // in particular, we want to make sure the clip (which is part
490 // of the geometry state) is latched together with the size but is
491 // latched immediately when no resizing is involved.
492
493 flags |= eDontUpdateGeometryState;
494 }
495 }
496
497 return LayerBase::doTransaction(flags);
498 }
499
isFixedSize() const500 bool Layer::isFixedSize() const {
501 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
502 }
503
isCropped() const504 bool Layer::isCropped() const {
505 return !mCurrentCrop.isEmpty();
506 }
507
508 // ----------------------------------------------------------------------------
509 // pageflip handling...
510 // ----------------------------------------------------------------------------
511
onPreComposition()512 bool Layer::onPreComposition() {
513 mRefreshPending = false;
514 return mQueuedFrames > 0;
515 }
516
lockPageFlip(bool & recomputeVisibleRegions)517 void Layer::lockPageFlip(bool& recomputeVisibleRegions)
518 {
519 ATRACE_CALL();
520
521 if (mQueuedFrames > 0) {
522
523 // if we've already called updateTexImage() without going through
524 // a composition step, we have to skip this layer at this point
525 // because we cannot call updateTeximage() without a corresponding
526 // compositionComplete() call.
527 // we'll trigger an update in onPreComposition().
528 if (mRefreshPending) {
529 mPostedDirtyRegion.clear();
530 return;
531 }
532
533 // Capture the old state of the layer for comparisons later
534 const bool oldOpacity = isOpaque();
535 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
536
537 // signal another event if we have more frames pending
538 if (android_atomic_dec(&mQueuedFrames) > 1) {
539 mFlinger->signalLayerUpdate();
540 }
541
542 struct Reject : public SurfaceTexture::BufferRejecter {
543 Layer::State& front;
544 Layer::State& current;
545 bool& recomputeVisibleRegions;
546 Reject(Layer::State& front, Layer::State& current,
547 bool& recomputeVisibleRegions)
548 : front(front), current(current),
549 recomputeVisibleRegions(recomputeVisibleRegions) {
550 }
551
552 virtual bool reject(const sp<GraphicBuffer>& buf,
553 const BufferQueue::BufferItem& item) {
554 if (buf == NULL) {
555 return false;
556 }
557
558 uint32_t bufWidth = buf->getWidth();
559 uint32_t bufHeight = buf->getHeight();
560
561 // check that we received a buffer of the right size
562 // (Take the buffer's orientation into account)
563 if (item.mTransform & Transform::ROT_90) {
564 swap(bufWidth, bufHeight);
565 }
566
567
568 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
569 if (front.active != front.requested) {
570
571 if (isFixedSize ||
572 (bufWidth == front.requested.w &&
573 bufHeight == front.requested.h))
574 {
575 // Here we pretend the transaction happened by updating the
576 // current and drawing states. Drawing state is only accessed
577 // in this thread, no need to have it locked
578 front.active = front.requested;
579
580 // We also need to update the current state so that
581 // we don't end-up overwriting the drawing state with
582 // this stale current state during the next transaction
583 //
584 // NOTE: We don't need to hold the transaction lock here
585 // because State::active is only accessed from this thread.
586 current.active = front.active;
587
588 // recompute visible region
589 recomputeVisibleRegions = true;
590 }
591
592 ALOGD_IF(DEBUG_RESIZE,
593 "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
594 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
595 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
596 this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
597 front.active.w, front.active.h,
598 front.active.crop.left,
599 front.active.crop.top,
600 front.active.crop.right,
601 front.active.crop.bottom,
602 front.active.crop.getWidth(),
603 front.active.crop.getHeight(),
604 front.requested.w, front.requested.h,
605 front.requested.crop.left,
606 front.requested.crop.top,
607 front.requested.crop.right,
608 front.requested.crop.bottom,
609 front.requested.crop.getWidth(),
610 front.requested.crop.getHeight());
611 }
612
613 if (!isFixedSize) {
614 if (front.active.w != bufWidth ||
615 front.active.h != bufHeight) {
616 // reject this buffer
617 return true;
618 }
619 }
620 return false;
621 }
622 };
623
624
625 Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
626
627 if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
628 // something happened!
629 recomputeVisibleRegions = true;
630 return;
631 }
632
633 // update the active buffer
634 mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
635 if (mActiveBuffer == NULL) {
636 // this can only happen if the very first buffer was rejected.
637 return;
638 }
639
640 mRefreshPending = true;
641 mFrameLatencyNeeded = true;
642 if (oldActiveBuffer == NULL) {
643 // the first time we receive a buffer, we need to trigger a
644 // geometry invalidation.
645 mFlinger->invalidateHwcGeometry();
646 }
647
648 Rect crop(mSurfaceTexture->getCurrentCrop());
649 const uint32_t transform(mSurfaceTexture->getCurrentTransform());
650 const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
651 if ((crop != mCurrentCrop) ||
652 (transform != mCurrentTransform) ||
653 (scalingMode != mCurrentScalingMode))
654 {
655 mCurrentCrop = crop;
656 mCurrentTransform = transform;
657 mCurrentScalingMode = scalingMode;
658 mFlinger->invalidateHwcGeometry();
659 }
660
661 if (oldActiveBuffer != NULL) {
662 uint32_t bufWidth = mActiveBuffer->getWidth();
663 uint32_t bufHeight = mActiveBuffer->getHeight();
664 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
665 bufHeight != uint32_t(oldActiveBuffer->height)) {
666 mFlinger->invalidateHwcGeometry();
667 }
668 }
669
670 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
671 if (oldOpacity != isOpaque()) {
672 recomputeVisibleRegions = true;
673 }
674
675 // FIXME: mPostedDirtyRegion = dirty & bounds
676 const Layer::State& front(drawingState());
677 mPostedDirtyRegion.set(front.active.w, front.active.h);
678
679 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
680 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
681 }
682 }
683
unlockPageFlip(const Transform & planeTransform,Region & outDirtyRegion)684 void Layer::unlockPageFlip(
685 const Transform& planeTransform, Region& outDirtyRegion)
686 {
687 ATRACE_CALL();
688
689 Region postedRegion(mPostedDirtyRegion);
690 if (!postedRegion.isEmpty()) {
691 mPostedDirtyRegion.clear();
692 if (!visibleRegionScreen.isEmpty()) {
693 // The dirty region is given in the layer's coordinate space
694 // transform the dirty region by the surface's transformation
695 // and the global transformation.
696 const Layer::State& s(drawingState());
697 const Transform tr(planeTransform * s.transform);
698 postedRegion = tr.transform(postedRegion);
699
700 // At this point, the dirty region is in screen space.
701 // Make sure it's constrained by the visible region (which
702 // is in screen space as well).
703 postedRegion.andSelf(visibleRegionScreen);
704 outDirtyRegion.orSelf(postedRegion);
705 }
706 }
707 }
708
dump(String8 & result,char * buffer,size_t SIZE) const709 void Layer::dump(String8& result, char* buffer, size_t SIZE) const
710 {
711 LayerBaseClient::dump(result, buffer, SIZE);
712
713 sp<const GraphicBuffer> buf0(mActiveBuffer);
714 uint32_t w0=0, h0=0, s0=0, f0=0;
715 if (buf0 != 0) {
716 w0 = buf0->getWidth();
717 h0 = buf0->getHeight();
718 s0 = buf0->getStride();
719 f0 = buf0->format;
720 }
721 snprintf(buffer, SIZE,
722 " "
723 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
724 " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
725 mFormat, w0, h0, s0,f0,
726 getTransformHint(), mQueuedFrames, mRefreshPending);
727
728 result.append(buffer);
729
730 if (mSurfaceTexture != 0) {
731 mSurfaceTexture->dump(result, " ", buffer, SIZE);
732 }
733 }
734
dumpStats(String8 & result,char * buffer,size_t SIZE) const735 void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
736 {
737 LayerBaseClient::dumpStats(result, buffer, SIZE);
738 const size_t o = mFrameLatencyOffset;
739 const DisplayHardware& hw(graphicPlane(0).displayHardware());
740 const nsecs_t period = hw.getRefreshPeriod();
741 result.appendFormat("%lld\n", period);
742 for (size_t i=0 ; i<128 ; i++) {
743 const size_t index = (o+i) % 128;
744 const nsecs_t time_app = mFrameStats[index].timestamp;
745 const nsecs_t time_set = mFrameStats[index].set;
746 const nsecs_t time_vsync = mFrameStats[index].vsync;
747 result.appendFormat("%lld\t%lld\t%lld\n",
748 time_app,
749 time_vsync,
750 time_set);
751 }
752 result.append("\n");
753 }
754
clearStats()755 void Layer::clearStats()
756 {
757 LayerBaseClient::clearStats();
758 memset(mFrameStats, 0, sizeof(mFrameStats));
759 }
760
getEffectiveUsage(uint32_t usage) const761 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
762 {
763 // TODO: should we do something special if mSecure is set?
764 if (mProtectedByApp) {
765 // need a hardware-protected path to external video sink
766 usage |= GraphicBuffer::USAGE_PROTECTED;
767 }
768 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
769 return usage;
770 }
771
getTransformHint() const772 uint32_t Layer::getTransformHint() const {
773 uint32_t orientation = 0;
774 if (!mFlinger->mDebugDisableTransformHint) {
775 orientation = getPlaneOrientation();
776 if (orientation & Transform::ROT_INVALID) {
777 orientation = 0;
778 }
779 }
780 return orientation;
781 }
782
783 // ---------------------------------------------------------------------------
784
785
786 }; // namespace android
787