2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
21 #include <sys/types.h>
24 #include <cutils/compiler.h>
25 #include <cutils/native_handle.h>
26 #include <cutils/properties.h>
28 #include <utils/Errors.h>
29 #include <utils/Log.h>
30 #include <utils/StopWatch.h>
31 #include <utils/Trace.h>
33 #include <ui/GraphicBuffer.h>
34 #include <ui/PixelFormat.h>
36 #include <gui/Surface.h>
39 #include "DisplayDevice.h"
40 #include "GLExtensions.h"
42 #include "SurfaceFlinger.h"
43 #include "SurfaceTextureLayer.h"
45 #include "DisplayHardware/HWComposer.h"
47 #define DEBUG_RESIZE 0
51 // ---------------------------------------------------------------------------
53 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
54 : LayerBaseClient(flinger, client),
58 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
59 mCurrentOpacity(true),
60 mRefreshPending(false),
61 mFrameLatencyNeeded(false),
62 mFormat(PIXEL_FORMAT_NONE),
63 mGLExtensions(GLExtensions::getInstance()),
66 mProtectedByApp(false)
68 mCurrentCrop.makeInvalid();
69 glGenTextures(1, &mTextureName);
72 void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
73 HWComposer::HWCLayerInterface* layer) {
74 LayerBaseClient::onLayerDisplayed(hw, layer);
76 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
80 void Layer::onFirstRef()
82 LayerBaseClient::onFirstRef();
84 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
85 sp<BufferQueue> bq = new SurfaceTextureLayer();
86 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
87 GL_TEXTURE_EXTERNAL_OES, false, bq);
89 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
90 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
91 mSurfaceFlingerConsumer->setSynchronousMode(true);
93 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
94 #warning "disabling triple buffering"
95 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
97 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
100 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
101 updateTransformHint(hw);
106 mFlinger->deleteTextureAsync(mTextureName);
109 void Layer::onFrameAvailable() {
110 android_atomic_inc(&mQueuedFrames);
111 mFlinger->signalLayerUpdate();
114 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
115 // in the purgatory list
116 void Layer::onRemoved()
118 mSurfaceFlingerConsumer->abandon();
121 void Layer::setName(const String8& name) {
122 LayerBase::setName(name);
123 mSurfaceFlingerConsumer->setName(name);
126 sp<ISurface> Layer::createSurface()
129 * This class provides an implementation of BnSurface (the "native" or
130 * "remote" side of the Binder IPC interface ISurface), and mixes in
131 * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
132 * this layer when the BSurface is destroyed.
134 * The idea is to provide a handle to the Layer through ISurface that
135 * is cleaned up automatically when the last reference to the ISurface
136 * goes away. (The references will be held on the "proxy" side, while
137 * the Layer exists on the "native" side.)
139 * The Layer has a reference to an instance of SurfaceFlinger's variant
140 * of GLConsumer, which holds a reference to the BufferQueue. The
141 * getSurfaceTexture() call returns a Binder interface reference for
142 * the producer interface of the buffer queue associated with the Layer.
144 class BSurface : public BnSurface, public LayerCleaner {
145 wp<const Layer> mOwner;
146 virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
147 sp<IGraphicBufferProducer> res;
148 sp<const Layer> that( mOwner.promote() );
150 res = that->mSurfaceFlingerConsumer->getBufferQueue();
155 BSurface(const sp<SurfaceFlinger>& flinger,
156 const sp<Layer>& layer)
157 : LayerCleaner(flinger, layer), mOwner(layer) { }
159 sp<ISurface> sur(new BSurface(mFlinger, this));
163 wp<IBinder> Layer::getSurfaceTextureBinder() const
165 return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
168 status_t Layer::setBuffers( uint32_t w, uint32_t h,
169 PixelFormat format, uint32_t flags)
171 // this surfaces pixel format
172 PixelFormatInfo info;
173 status_t err = getPixelFormatInfo(format, &info);
175 ALOGE("unsupported pixelformat %d", format);
179 uint32_t const maxSurfaceDims = min(
180 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
182 // never allow a surface larger than what our underlying GL implementation
184 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
185 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
191 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
192 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
193 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
194 mCurrentOpacity = getOpacityForFormat(format);
196 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
197 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
198 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
203 Rect Layer::computeBufferCrop() const {
204 // Start with the SurfaceFlingerConsumer's buffer crop...
206 if (!mCurrentCrop.isEmpty()) {
208 } else if (mActiveBuffer != NULL){
209 crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
215 // ... then reduce that in the same proportions as the window crop reduces
217 const State& s(drawingState());
218 if (!s.active.crop.isEmpty()) {
219 // Transform the window crop to match the buffer coordinate system,
220 // which means using the inverse of the current transform set on the
221 // SurfaceFlingerConsumer.
222 uint32_t invTransform = mCurrentTransform;
223 int winWidth = s.active.w;
224 int winHeight = s.active.h;
225 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
226 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
227 NATIVE_WINDOW_TRANSFORM_FLIP_H;
228 winWidth = s.active.h;
229 winHeight = s.active.w;
231 Rect winCrop = s.active.crop.transform(invTransform,
232 s.active.w, s.active.h);
234 float xScale = float(crop.width()) / float(winWidth);
235 float yScale = float(crop.height()) / float(winHeight);
236 crop.left += int(ceilf(float(winCrop.left) * xScale));
237 crop.top += int(ceilf(float(winCrop.top) * yScale));
238 crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
239 crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
245 void Layer::setGeometry(
246 const sp<const DisplayDevice>& hw,
247 HWComposer::HWCLayerInterface& layer)
249 LayerBaseClient::setGeometry(hw, layer);
252 layer.setSkip(false);
254 if (isSecure() && !hw->isSecure()) {
258 const State& s(drawingState());
259 layer.setPlaneAlpha(s.alpha);
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)
269 const Transform bufferOrientation(mCurrentTransform);
270 const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
272 // this gives us only the "orientation" component of the transform
273 const uint32_t finalTransform = tr.getOrientation();
275 // we can only handle simple transformation
276 if (finalTransform & Transform::ROT_INVALID) {
279 layer.setTransform(finalTransform);
281 layer.setCrop(computeBufferCrop());
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);
292 void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
293 HWComposer::HWCLayerInterface& layer) {
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.
299 if (layer.getCompositionType() == HWC_OVERLAY) {
300 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
302 fenceFd = fence->dup();
304 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
308 layer.setAcquireFenceFd(fenceFd);
311 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
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.
321 // If there is nothing under us, we paint the screen in black, otherwise
322 // we just skip this update.
324 // figure out if there is something below us
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))
333 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
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);
343 // Bind the current buffer to the GL texture, and wait for it to be
344 // ready for us to draw into.
345 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
346 if (err != NO_ERROR) {
347 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
348 // Go ahead and draw the buffer anyway; no matter what we do the screen
349 // is probably going to have something visibly wrong.
352 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
354 if (!blackOutLayer) {
355 // TODO: we could be more subtle with isFixedSize()
356 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
358 // Query the texture matrix given our current filtering mode.
359 float textureMatrix[16];
360 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
361 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
363 // Set things up for texturing.
364 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
365 GLenum filter = GL_NEAREST;
369 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
370 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
371 glMatrixMode(GL_TEXTURE);
372 glLoadMatrixf(textureMatrix);
373 glMatrixMode(GL_MODELVIEW);
374 glDisable(GL_TEXTURE_2D);
375 glEnable(GL_TEXTURE_EXTERNAL_OES);
377 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
378 glMatrixMode(GL_TEXTURE);
380 glMatrixMode(GL_MODELVIEW);
381 glDisable(GL_TEXTURE_EXTERNAL_OES);
382 glEnable(GL_TEXTURE_2D);
385 drawWithOpenGL(hw, clip);
387 glDisable(GL_TEXTURE_EXTERNAL_OES);
388 glDisable(GL_TEXTURE_2D);
391 // As documented in libhardware header, formats in the range
392 // 0x100 - 0x1FF are specific to the HAL implementation, and
393 // are known to have no alpha channel
394 // TODO: move definition for device-specific range into
395 // hardware.h, instead of using hard-coded values here.
396 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
398 bool Layer::getOpacityForFormat(uint32_t format)
400 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
403 PixelFormatInfo info;
404 status_t err = getPixelFormatInfo(PixelFormat(format), &info);
405 // in case of error (unknown format), we assume no blending
406 return (err || info.h_alpha <= info.l_alpha);
410 bool Layer::isOpaque() const
412 // if we don't have a buffer yet, we're translucent regardless of the
413 // layer's opaque flag.
414 if (mActiveBuffer == 0) {
418 // if the layer has the opaque flag, then we're always opaque,
419 // otherwise we use the current buffer's format.
420 return mOpaqueLayer || mCurrentOpacity;
423 bool Layer::isProtected() const
425 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
426 return (activeBuffer != 0) &&
427 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
430 uint32_t Layer::doTransaction(uint32_t flags)
434 const Layer::State& front(drawingState());
435 const Layer::State& temp(currentState());
437 const bool sizeChanged = (temp.requested.w != front.requested.w) ||
438 (temp.requested.h != front.requested.h);
441 // the size changed, we need to ask our client to request a new buffer
442 ALOGD_IF(DEBUG_RESIZE,
443 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
444 " current={ 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 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
447 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
448 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
449 temp.active.w, temp.active.h,
450 temp.active.crop.left,
451 temp.active.crop.top,
452 temp.active.crop.right,
453 temp.active.crop.bottom,
454 temp.active.crop.getWidth(),
455 temp.active.crop.getHeight(),
456 temp.requested.w, temp.requested.h,
457 temp.requested.crop.left,
458 temp.requested.crop.top,
459 temp.requested.crop.right,
460 temp.requested.crop.bottom,
461 temp.requested.crop.getWidth(),
462 temp.requested.crop.getHeight(),
463 front.active.w, front.active.h,
464 front.active.crop.left,
465 front.active.crop.top,
466 front.active.crop.right,
467 front.active.crop.bottom,
468 front.active.crop.getWidth(),
469 front.active.crop.getHeight(),
470 front.requested.w, front.requested.h,
471 front.requested.crop.left,
472 front.requested.crop.top,
473 front.requested.crop.right,
474 front.requested.crop.bottom,
475 front.requested.crop.getWidth(),
476 front.requested.crop.getHeight());
478 // record the new size, form this point on, when the client request
479 // a buffer, it'll get the new size.
480 mSurfaceFlingerConsumer->setDefaultBufferSize(
481 temp.requested.w, temp.requested.h);
484 if (!isFixedSize()) {
486 const bool resizePending = (temp.requested.w != temp.active.w) ||
487 (temp.requested.h != temp.active.h);
490 // don't let LayerBase::doTransaction update the drawing state
491 // if we have a pending resize, unless we are in fixed-size mode.
492 // the drawing state will be updated only once we receive a buffer
493 // with the correct size.
495 // in particular, we want to make sure the clip (which is part
496 // of the geometry state) is latched together with the size but is
497 // latched immediately when no resizing is involved.
499 flags |= eDontUpdateGeometryState;
503 return LayerBase::doTransaction(flags);
506 bool Layer::isFixedSize() const {
507 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
510 bool Layer::isCropped() const {
511 return !mCurrentCrop.isEmpty();
514 // ----------------------------------------------------------------------------
515 // pageflip handling...
516 // ----------------------------------------------------------------------------
518 bool Layer::onPreComposition() {
519 mRefreshPending = false;
520 return mQueuedFrames > 0;
523 void Layer::onPostComposition() {
524 if (mFrameLatencyNeeded) {
525 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
526 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
528 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
529 if (frameReadyFence != NULL) {
530 mFrameTracker.setFrameReadyFence(frameReadyFence);
532 // There was no fence for this frame, so assume that it was ready
533 // to be presented at the desired present time.
534 mFrameTracker.setFrameReadyTime(desiredPresentTime);
537 const HWComposer& hwc = mFlinger->getHwComposer();
538 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
539 if (presentFence != NULL) {
540 mFrameTracker.setActualPresentFence(presentFence);
542 // The HWC doesn't support present fences, so use the refresh
543 // timestamp instead.
544 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
545 mFrameTracker.setActualPresentTime(presentTime);
548 mFrameTracker.advanceFrame();
549 mFrameLatencyNeeded = false;
553 bool Layer::isVisible() const {
554 return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
557 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
561 Region outDirtyRegion;
562 if (mQueuedFrames > 0) {
564 // if we've already called updateTexImage() without going through
565 // a composition step, we have to skip this layer at this point
566 // because we cannot call updateTeximage() without a corresponding
567 // compositionComplete() call.
568 // we'll trigger an update in onPreComposition().
569 if (mRefreshPending) {
570 return outDirtyRegion;
573 // Capture the old state of the layer for comparisons later
574 const bool oldOpacity = isOpaque();
575 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
577 // signal another event if we have more frames pending
578 if (android_atomic_dec(&mQueuedFrames) > 1) {
579 mFlinger->signalLayerUpdate();
582 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
584 Layer::State& current;
585 bool& recomputeVisibleRegions;
586 Reject(Layer::State& front, Layer::State& current,
587 bool& recomputeVisibleRegions)
588 : front(front), current(current),
589 recomputeVisibleRegions(recomputeVisibleRegions) {
592 virtual bool reject(const sp<GraphicBuffer>& buf,
593 const BufferQueue::BufferItem& item) {
598 uint32_t bufWidth = buf->getWidth();
599 uint32_t bufHeight = buf->getHeight();
601 // check that we received a buffer of the right size
602 // (Take the buffer's orientation into account)
603 if (item.mTransform & Transform::ROT_90) {
604 swap(bufWidth, bufHeight);
608 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
609 if (front.active != front.requested) {
612 (bufWidth == front.requested.w &&
613 bufHeight == front.requested.h))
615 // Here we pretend the transaction happened by updating the
616 // current and drawing states. Drawing state is only accessed
617 // in this thread, no need to have it locked
618 front.active = front.requested;
620 // We also need to update the current state so that
621 // we don't end-up overwriting the drawing state with
622 // this stale current state during the next transaction
624 // NOTE: We don't need to hold the transaction lock here
625 // because State::active is only accessed from this thread.
626 current.active = front.active;
628 // recompute visible region
629 recomputeVisibleRegions = true;
632 ALOGD_IF(DEBUG_RESIZE,
633 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
634 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
635 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
636 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
637 front.active.w, front.active.h,
638 front.active.crop.left,
639 front.active.crop.top,
640 front.active.crop.right,
641 front.active.crop.bottom,
642 front.active.crop.getWidth(),
643 front.active.crop.getHeight(),
644 front.requested.w, front.requested.h,
645 front.requested.crop.left,
646 front.requested.crop.top,
647 front.requested.crop.right,
648 front.requested.crop.bottom,
649 front.requested.crop.getWidth(),
650 front.requested.crop.getHeight());
654 if (front.active.w != bufWidth ||
655 front.active.h != bufHeight) {
656 // reject this buffer
665 Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
667 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
668 // something happened!
669 recomputeVisibleRegions = true;
670 return outDirtyRegion;
673 // update the active buffer
674 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
675 if (mActiveBuffer == NULL) {
676 // this can only happen if the very first buffer was rejected.
677 return outDirtyRegion;
680 mRefreshPending = true;
681 mFrameLatencyNeeded = true;
682 if (oldActiveBuffer == NULL) {
683 // the first time we receive a buffer, we need to trigger a
684 // geometry invalidation.
685 recomputeVisibleRegions = true;
688 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
689 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
690 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
691 if ((crop != mCurrentCrop) ||
692 (transform != mCurrentTransform) ||
693 (scalingMode != mCurrentScalingMode))
696 mCurrentTransform = transform;
697 mCurrentScalingMode = scalingMode;
698 recomputeVisibleRegions = true;
701 if (oldActiveBuffer != NULL) {
702 uint32_t bufWidth = mActiveBuffer->getWidth();
703 uint32_t bufHeight = mActiveBuffer->getHeight();
704 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
705 bufHeight != uint32_t(oldActiveBuffer->height)) {
706 recomputeVisibleRegions = true;
710 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
711 if (oldOpacity != isOpaque()) {
712 recomputeVisibleRegions = true;
715 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
716 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
718 // FIXME: postedRegion should be dirty & bounds
719 const Layer::State& front(drawingState());
720 Region dirtyRegion(Rect(front.active.w, front.active.h));
722 // transform the dirty region to window-manager space
723 outDirtyRegion = (front.transform.transform(dirtyRegion));
725 return outDirtyRegion;
728 void Layer::dump(String8& result, char* buffer, size_t SIZE) const
730 LayerBaseClient::dump(result, buffer, SIZE);
732 sp<const GraphicBuffer> buf0(mActiveBuffer);
733 uint32_t w0=0, h0=0, s0=0, f0=0;
735 w0 = buf0->getWidth();
736 h0 = buf0->getHeight();
737 s0 = buf0->getStride();
740 snprintf(buffer, SIZE,
742 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
743 " queued-frames=%d, mRefreshPending=%d\n",
744 mFormat, w0, h0, s0,f0,
745 mQueuedFrames, mRefreshPending);
747 result.append(buffer);
749 if (mSurfaceFlingerConsumer != 0) {
750 mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE);
754 void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
756 LayerBaseClient::dumpStats(result, buffer, SIZE);
757 mFrameTracker.dump(result);
760 void Layer::clearStats()
762 LayerBaseClient::clearStats();
763 mFrameTracker.clear();
766 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
768 // TODO: should we do something special if mSecure is set?
769 if (mProtectedByApp) {
770 // need a hardware-protected path to external video sink
771 usage |= GraphicBuffer::USAGE_PROTECTED;
773 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
777 void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
778 uint32_t orientation = 0;
779 if (!mFlinger->mDebugDisableTransformHint) {
780 // The transform hint is used to improve performance, but we can
781 // only have a single transform hint, it cannot
782 // apply to all displays.
783 const Transform& planeTransform(hw->getTransform());
784 orientation = planeTransform.getOrientation();
785 if (orientation & Transform::ROT_INVALID) {
789 mSurfaceFlingerConsumer->setTransformHint(orientation);
792 // ---------------------------------------------------------------------------
795 }; // namespace android