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.
19 #include <sys/types.h>
21 #include <utils/Errors.h>
22 #include <utils/Log.h>
23 #include <binder/IPCThreadState.h>
24 #include <binder/IServiceManager.h>
27 #include <GLES/glext.h>
29 #include <hardware/hardware.h>
32 #include "LayerBase.h"
33 #include "SurfaceFlinger.h"
34 #include "DisplayHardware/DisplayHardware.h"
35 #include "TextureManager.h"
40 // ---------------------------------------------------------------------------
42 int32_t LayerBase::sSequence = 1;
44 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
45 : dpy(display), contentDirty(false),
46 sequence(uint32_t(android_atomic_inc(&sSequence))),
48 mNeedsFiltering(false),
52 mPremultipliedAlpha(true), mName("unnamed"), mDebug(false),
55 const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
56 mFlags = hw.getFlags();
57 mBufferCrop.makeInvalid();
61 LayerBase::~LayerBase()
65 void LayerBase::setName(const String8& name) {
69 String8 LayerBase::getName() const {
73 const GraphicPlane& LayerBase::graphicPlane(int dpy) const
75 return mFlinger->graphicPlane(dpy);
78 GraphicPlane& LayerBase::graphicPlane(int dpy)
80 return mFlinger->graphicPlane(dpy);
83 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
85 uint32_t layerFlags = 0;
86 if (flags & ISurfaceComposer::eHidden)
87 layerFlags = ISurfaceComposer::eLayerHidden;
89 if (flags & ISurfaceComposer::eNonPremultiplied)
90 mPremultipliedAlpha = false;
95 mCurrentState.requested_w = w;
96 mCurrentState.requested_h = h;
97 mCurrentState.alpha = 0xFF;
98 mCurrentState.flags = layerFlags;
99 mCurrentState.sequence = 0;
100 mCurrentState.transform.set(0, 0);
102 // drawing state & current state are identical
103 mDrawingState = mCurrentState;
106 void LayerBase::commitTransaction() {
107 mDrawingState = mCurrentState;
109 void LayerBase::forceVisibilityTransaction() {
110 // this can be called without SurfaceFlinger.mStateLock, but if we
111 // can atomically increment the sequence number, it doesn't matter.
112 android_atomic_inc(&mCurrentState.sequence);
113 requestTransaction();
115 bool LayerBase::requestTransaction() {
116 int32_t old = setTransactionFlags(eTransactionNeeded);
117 return ((old & eTransactionNeeded) == 0);
119 uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
120 return android_atomic_and(~flags, &mTransactionFlags) & flags;
122 uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
123 return android_atomic_or(flags, &mTransactionFlags);
126 bool LayerBase::setPosition(int32_t x, int32_t y) {
127 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
129 mCurrentState.sequence++;
130 mCurrentState.transform.set(x, y);
131 requestTransaction();
134 bool LayerBase::setLayer(uint32_t z) {
135 if (mCurrentState.z == z)
137 mCurrentState.sequence++;
139 requestTransaction();
142 bool LayerBase::setSize(uint32_t w, uint32_t h) {
143 if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
145 mCurrentState.requested_w = w;
146 mCurrentState.requested_h = h;
147 requestTransaction();
150 bool LayerBase::setAlpha(uint8_t alpha) {
151 if (mCurrentState.alpha == alpha)
153 mCurrentState.sequence++;
154 mCurrentState.alpha = alpha;
155 requestTransaction();
158 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
159 mCurrentState.sequence++;
160 mCurrentState.transform.set(
161 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
162 requestTransaction();
165 bool LayerBase::setTransparentRegionHint(const Region& transparent) {
166 mCurrentState.sequence++;
167 mCurrentState.transparentRegion = transparent;
168 requestTransaction();
171 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
172 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
173 if (mCurrentState.flags == newFlags)
175 mCurrentState.sequence++;
176 mCurrentState.flags = newFlags;
177 requestTransaction();
181 Rect LayerBase::visibleBounds() const
183 return mTransformedBounds;
186 void LayerBase::setVisibleRegion(const Region& visibleRegion) {
187 // always called from main thread
188 visibleRegionScreen = visibleRegion;
191 void LayerBase::setCoveredRegion(const Region& coveredRegion) {
192 // always called from main thread
193 coveredRegionScreen = coveredRegion;
196 uint32_t LayerBase::doTransaction(uint32_t flags)
198 const Layer::State& front(drawingState());
199 const Layer::State& temp(currentState());
201 if ((front.requested_w != temp.requested_w) ||
202 (front.requested_h != temp.requested_h)) {
203 // resize the layer, set the physical size to the requested size
204 Layer::State& editTemp(currentState());
205 editTemp.w = temp.requested_w;
206 editTemp.h = temp.requested_h;
209 if ((front.w != temp.w) || (front.h != temp.h)) {
210 // invalidate and recompute the visible regions if needed
211 flags |= Layer::eVisibleRegion;
214 if (temp.sequence != front.sequence) {
215 // invalidate and recompute the visible regions if needed
216 flags |= eVisibleRegion;
217 this->contentDirty = true;
219 // we may use linear filtering, if the matrix scales us
220 const uint8_t type = temp.transform.getType();
221 mNeedsFiltering = (!temp.transform.preserveRects() ||
222 (type >= Transform::SCALE));
225 // Commit the transaction
230 void LayerBase::validateVisibility(const Transform& planeTransform)
232 const Layer::State& s(drawingState());
233 const Transform tr(planeTransform * s.transform);
234 const bool transformed = tr.transformed();
238 tr.transform(mVertices[0], 0, 0);
239 tr.transform(mVertices[1], 0, h);
240 tr.transform(mVertices[2], w, h);
241 tr.transform(mVertices[3], w, 0);
242 if (UNLIKELY(transformed)) {
243 // NOTE: here we could also punt if we have too many rectangles
244 // in the transparent region
245 if (tr.preserveRects()) {
246 // transform the transparent region
247 transparentRegionScreen = tr.transform(s.transparentRegion);
249 // transformation too complex, can't do the transparent region
251 transparentRegionScreen.clear();
254 transparentRegionScreen = s.transparentRegion;
257 // cache a few things...
258 mOrientation = tr.getOrientation();
259 mTransformedBounds = tr.makeBounds(w, h);
264 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
268 void LayerBase::unlockPageFlip(
269 const Transform& planeTransform, Region& outDirtyRegion)
271 if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
272 outDirtyRegion.orSelf(visibleRegionScreen);
276 void LayerBase::invalidate()
278 if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
279 mFlinger->signalEvent();
283 void LayerBase::drawRegion(const Region& reg) const
285 Region::const_iterator it = reg.begin();
286 Region::const_iterator const end = reg.end();
289 const DisplayHardware& hw(graphicPlane(0).displayHardware());
290 const int32_t fbWidth = hw.getWidth();
291 const int32_t fbHeight = hw.getHeight();
292 const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 },
293 { fbWidth, fbHeight }, { 0, fbHeight } };
294 glVertexPointer(2, GL_SHORT, 0, vertices);
296 const Rect& r = *it++;
297 const GLint sy = fbHeight - (r.top + r.height());
298 glScissor(r.left, sy, r.width(), r.height());
299 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
304 void LayerBase::draw(const Region& clip) const
307 glEnable(GL_SCISSOR_TEST);
312 void LayerBase::drawForSreenShot() const
314 const DisplayHardware& hw(graphicPlane(0).displayHardware());
315 onDraw( Region(hw.bounds()) );
318 void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
319 GLclampf green, GLclampf blue,
320 GLclampf alpha) const
322 const DisplayHardware& hw(graphicPlane(0).displayHardware());
323 const uint32_t fbHeight = hw.getHeight();
324 glColor4f(red,green,blue,alpha);
326 TextureManager::deactivateTextures();
329 glDisable(GL_DITHER);
331 Region::const_iterator it = clip.begin();
332 Region::const_iterator const end = clip.end();
333 glEnable(GL_SCISSOR_TEST);
334 glVertexPointer(2, GL_FLOAT, 0, mVertices);
336 const Rect& r = *it++;
337 const GLint sy = fbHeight - (r.top + r.height());
338 glScissor(r.left, sy, r.width(), r.height());
339 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
343 void LayerBase::clearWithOpenGL(const Region& clip) const
345 clearWithOpenGL(clip,0,0,0,0);
348 template <typename T>
350 void swap(T& a, T& b) {
356 void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
358 const DisplayHardware& hw(graphicPlane(0).displayHardware());
359 const uint32_t fbHeight = hw.getHeight();
360 const State& s(drawingState());
363 TextureManager::activateTexture(texture, needsFiltering());
364 uint32_t width = texture.width;
365 uint32_t height = texture.height;
367 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
368 if (UNLIKELY(s.alpha < 0xFF)) {
369 const GLfloat alpha = s.alpha * (1.0f/255.0f);
370 if (mPremultipliedAlpha) {
371 glColor4f(alpha, alpha, alpha, alpha);
373 glColor4f(1, 1, 1, alpha);
376 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
377 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
379 glColor4f(1, 1, 1, 1);
380 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
381 if (needsBlending()) {
383 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
390 * compute texture coordinates
391 * here, we handle NPOT, cropping and buffer transformations
394 GLfloat cl, ct, cr, cb;
395 if (!mBufferCrop.isEmpty()) {
397 const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width;
398 const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height;
399 cl = mBufferCrop.left * us;
400 ct = mBufferCrop.top * vs;
401 cr = mBufferCrop.right * us;
402 cb = mBufferCrop.bottom * vs;
406 cr = (texture.NPOTAdjust ? texture.wScale : 1.0f);
407 cb = (texture.NPOTAdjust ? texture.hScale : 1.0f);
411 * For the buffer transformation, we apply the rotation last.
412 * Since we're transforming the texture-coordinates, we need
413 * to apply the inverse of the buffer transformation:
414 * inverse( FLIP_V -> FLIP_H -> ROT_90 )
415 * <=> inverse( ROT_90 * FLIP_H * FLIP_V )
416 * = inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90)
417 * = FLIP_V * FLIP_H * ROT_270
418 * <=> ROT_270 -> FLIP_H -> FLIP_V
420 * The rotation is performed first, in the texture coordinate space.
430 // name of the corners in the texture map
431 LB = 0, // left-bottom
434 RB = 3 // right-bottom
437 // vertices in screen space
443 // the texture's source is rotated
444 uint32_t transform = mBufferTransform;
445 if (transform & HAL_TRANSFORM_ROT_90) {
451 if (transform & HAL_TRANSFORM_FLIP_V) {
455 if (transform & HAL_TRANSFORM_FLIP_H) {
460 TexCoords texCoords[4];
461 texCoords[vLT].u = cl;
462 texCoords[vLT].v = ct;
463 texCoords[vLB].u = cl;
464 texCoords[vLB].v = cb;
465 texCoords[vRB].u = cr;
466 texCoords[vRB].v = cb;
467 texCoords[vRT].u = cr;
468 texCoords[vRT].v = ct;
470 if (needsDithering()) {
473 glDisable(GL_DITHER);
476 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
477 glVertexPointer(2, GL_FLOAT, 0, mVertices);
478 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
480 Region::const_iterator it = clip.begin();
481 Region::const_iterator const end = clip.end();
483 const Rect& r = *it++;
484 const GLint sy = fbHeight - (r.top + r.height());
485 glScissor(r.left, sy, r.width(), r.height());
486 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
488 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
491 void LayerBase::setBufferCrop(const Rect& crop) {
492 if (!crop.isEmpty()) {
497 void LayerBase::setBufferTransform(uint32_t transform) {
498 mBufferTransform = transform;
501 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
503 const Layer::State& s(drawingState());
504 snprintf(buffer, SIZE,
507 "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
508 "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
509 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
510 getTypeId(), this, s.z, tx(), ty(), s.w, s.h,
511 needsBlending(), needsDithering(), contentDirty,
513 s.transform[0][0], s.transform[0][1],
514 s.transform[1][0], s.transform[1][1]);
515 result.append(buffer);
518 void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
520 LayerBase::dump(result, scratch, size);
524 // ---------------------------------------------------------------------------
526 int32_t LayerBaseClient::sIdentity = 1;
528 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
529 const sp<Client>& client)
530 : LayerBase(flinger, display), mClientRef(client),
531 mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
535 LayerBaseClient::~LayerBaseClient()
537 sp<Client> c(mClientRef.promote());
539 c->detachLayer(this);
543 sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
546 Mutex::Autolock _l(mLock);
547 s = mClientSurface.promote();
555 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
557 return new Surface(mFlinger, mIdentity,
558 const_cast<LayerBaseClient *>(this));
561 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
563 LayerBase::dump(result, buffer, SIZE);
565 sp<Client> client(mClientRef.promote());
566 snprintf(buffer, SIZE,
568 " client=%p, identity=%u\n",
570 client.get(), getIdentity());
572 result.append(buffer);
576 void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
578 LayerBaseClient::dump(result, scratch, size);
581 // ---------------------------------------------------------------------------
583 LayerBaseClient::Surface::Surface(
584 const sp<SurfaceFlinger>& flinger,
586 const sp<LayerBaseClient>& owner)
587 : mFlinger(flinger), mIdentity(identity), mOwner(owner)
591 LayerBaseClient::Surface::~Surface()
594 * This is a good place to clean-up all client resources
597 // destroy client resources
598 sp<LayerBaseClient> layer = getOwner();
600 mFlinger->destroySurface(layer);
604 sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
605 sp<LayerBaseClient> owner(mOwner.promote());
609 status_t LayerBaseClient::Surface::onTransact(
610 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
613 case REGISTER_BUFFERS:
614 case UNREGISTER_BUFFERS:
617 if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
618 IPCThreadState* ipc = IPCThreadState::self();
619 const int pid = ipc->getCallingPid();
620 const int uid = ipc->getCallingUid();
621 LOGE("Permission Denial: "
622 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
623 return PERMISSION_DENIED;
627 return BnSurface::onTransact(code, data, reply, flags);
630 sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int bufferIdx,
631 uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
636 status_t LayerBaseClient::Surface::setBufferCount(int bufferCount)
638 return INVALID_OPERATION;
641 status_t LayerBaseClient::Surface::registerBuffers(
642 const ISurface::BufferHeap& buffers)
644 return INVALID_OPERATION;
647 void LayerBaseClient::Surface::postBuffer(ssize_t offset)
651 void LayerBaseClient::Surface::unregisterBuffers()
655 sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
656 uint32_t w, uint32_t h, int32_t format, int32_t orientation)
661 // ---------------------------------------------------------------------------
663 }; // namespace android