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