blob: 13201db04ce081facd8f1baa16344ba465344ca1 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
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
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080017#include <stdlib.h>
18#include <stdint.h>
19#include <sys/types.h>
20
21#include <cutils/properties.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070022#include <cutils/native_handle.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080023
24#include <utils/Errors.h>
25#include <utils/Log.h>
26#include <utils/StopWatch.h>
27
28#include <ui/PixelFormat.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070029#include <ui/Surface.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080030
Mathias Agopiancbb288b2009-09-07 16:32:45 -070031#include "Buffer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080032#include "clz.h"
33#include "Layer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include "SurfaceFlinger.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080035#include "DisplayHardware/DisplayHardware.h"
36
37
38#define DEBUG_RESIZE 0
39
40
41namespace android {
42
43// ---------------------------------------------------------------------------
44
45const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
46const char* const Layer::typeID = "Layer";
47
48// ---------------------------------------------------------------------------
49
Mathias Agopiancbb288b2009-09-07 16:32:45 -070050Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
51 const sp<Client>& c, int32_t i)
Mathias Agopian48d819a2009-09-10 19:41:18 -070052 : LayerBaseClient(flinger, display, c, i),
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053 mSecure(false),
Mathias Agopian401c2572009-09-23 19:16:27 -070054 mNeedsBlending(true),
55 mNeedsDithering(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080056{
57 // no OpenGL operation is possible here, since we might not be
58 // in the OpenGL thread.
Mathias Agopiancbb288b2009-09-07 16:32:45 -070059 mFrontBufferIndex = lcblk->getFrontBuffer();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080060}
61
62Layer::~Layer()
63{
Mathias Agopian0aa758d2009-04-22 15:23:34 -070064 destroy();
65 // the actual buffers will be destroyed here
Mathias Agopian48d819a2009-09-10 19:41:18 -070066}
Mathias Agopiancbb288b2009-09-07 16:32:45 -070067
Mathias Agopian0aa758d2009-04-22 15:23:34 -070068void Layer::destroy()
69{
Mathias Agopiancbb288b2009-09-07 16:32:45 -070070 for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -070071 if (mTextures[i].name != -1U) {
Mathias Agopian550b79f2009-04-22 15:49:28 -070072 glDeleteTextures(1, &mTextures[i].name);
Mathias Agopian0aa758d2009-04-22 15:23:34 -070073 mTextures[i].name = -1U;
Mathias Agopian076b1cc2009-04-10 14:24:30 -070074 }
75 if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
76 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
77 eglDestroyImageKHR(dpy, mTextures[i].image);
Mathias Agopian0aa758d2009-04-22 15:23:34 -070078 mTextures[i].image = EGL_NO_IMAGE_KHR;
Mathias Agopian076b1cc2009-04-10 14:24:30 -070079 }
Mathias Agopian48d819a2009-09-10 19:41:18 -070080 Mutex::Autolock _l(mLock);
Mathias Agopiancbb288b2009-09-07 16:32:45 -070081 mBuffers[i].clear();
Mathias Agopian48d819a2009-09-10 19:41:18 -070082 mWidth = mHeight = 0;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080083 }
Mathias Agopian8c0a3d72009-09-23 16:44:00 -070084 mSurface.clear();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080085}
86
Mathias Agopian076b1cc2009-04-10 14:24:30 -070087sp<LayerBaseClient::Surface> Layer::createSurface() const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080088{
89 return mSurface;
90}
91
Mathias Agopian9a112062009-04-17 19:36:26 -070092status_t Layer::ditch()
93{
Mathias Agopian0aa758d2009-04-22 15:23:34 -070094 // the layer is not on screen anymore. free as much resources as possible
Mathias Agopian8c0a3d72009-09-23 16:44:00 -070095 destroy();
Mathias Agopian9a112062009-04-17 19:36:26 -070096 return NO_ERROR;
97}
98
Mathias Agopianf9d93272009-06-19 17:00:27 -070099status_t Layer::setBuffers( uint32_t w, uint32_t h,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800100 PixelFormat format, uint32_t flags)
101{
Mathias Agopian401c2572009-09-23 19:16:27 -0700102 // this surfaces pixel format
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800103 PixelFormatInfo info;
104 status_t err = getPixelFormatInfo(format, &info);
105 if (err) return err;
106
Mathias Agopian401c2572009-09-23 19:16:27 -0700107 // the display's pixel format
108 const DisplayHardware& hw(graphicPlane(0).displayHardware());
109 PixelFormatInfo displayInfo;
110 getPixelFormatInfo(hw.getFormat(), &displayInfo);
111
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700112 uint32_t bufferFlags = 0;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700113 if (flags & ISurfaceComposer::eSecure)
114 bufferFlags |= Buffer::SECURE;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800115
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700116 mFormat = format;
117 mWidth = w;
118 mHeight = h;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700119 mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800120 mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
Mathias Agopian401c2572009-09-23 19:16:27 -0700121
122 // we use the red index
123 int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
124 int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
125 mNeedsDithering = layerRedsize > displayRedSize;
126
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700127 mBufferFlags = bufferFlags;
128 for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
129 mBuffers[i] = new Buffer();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800130 }
Mathias Agopian9a112062009-04-17 19:36:26 -0700131 mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800132 return NO_ERROR;
133}
134
135void Layer::reloadTexture(const Region& dirty)
136{
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700137 Mutex::Autolock _l(mLock);
138 sp<Buffer> buffer(getFrontBuffer());
Mathias Agopian0926f502009-05-04 14:17:04 -0700139 if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700140 int index = mFrontBufferIndex;
141 if (LIKELY(!mTextures[index].dirty)) {
142 glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
143 } else {
144 // we need to recreate the texture
145 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
146
147 // create the new texture name if needed
148 if (UNLIKELY(mTextures[index].name == -1U)) {
149 mTextures[index].name = createTexture();
150 } else {
151 glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
152 }
153
154 // free the previous image
155 if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
156 eglDestroyImageKHR(dpy, mTextures[index].image);
157 mTextures[index].image = EGL_NO_IMAGE_KHR;
158 }
159
160 // construct an EGL_NATIVE_BUFFER_ANDROID
161 android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
162
163 // create the new EGLImageKHR
164 const EGLint attrs[] = {
165 EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
166 EGL_NONE, EGL_NONE
167 };
168 mTextures[index].image = eglCreateImageKHR(
169 dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
170 (EGLClientBuffer)clientBuf, attrs);
171
172 LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR,
173 "eglCreateImageKHR() failed. err=0x%4x",
174 eglGetError());
175
176 if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
177 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
178 (GLeglImageOES)mTextures[index].image);
179 GLint error = glGetError();
180 if (UNLIKELY(error != GL_NO_ERROR)) {
181 // this failed, for instance, because we don't support
182 // NPOT.
183 // FIXME: do something!
Mathias Agopian6d9f6982009-09-17 19:19:08 -0700184 LOGD("layer=%p, glEGLImageTargetTexture2DOES(%p) "
Mathias Agopian816d7d02009-09-14 18:10:30 -0700185 "failed err=0x%04x",
186 this, mTextures[index].image, error);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700187 mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
188 } else {
189 // Everything went okay!
Mathias Agopian1fed11c2009-06-23 18:08:22 -0700190 mTextures[index].dirty = false;
191 mTextures[index].width = clientBuf->width;
192 mTextures[index].height = clientBuf->height;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700193 }
194 }
195 }
196 } else {
197 GGLSurface t;
Mathias Agopian0926f502009-05-04 14:17:04 -0700198 status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY);
199 LOGE_IF(res, "error %d (%s) locking buffer %p",
200 res, strerror(res), buffer.get());
201 if (res == NO_ERROR) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700202 if (UNLIKELY(mTextures[0].name == -1U)) {
203 mTextures[0].name = createTexture();
204 }
Mathias Agopian1fed11c2009-06-23 18:08:22 -0700205 loadTexture(&mTextures[0], mTextures[0].name, dirty, t);
Mathias Agopian0926f502009-05-04 14:17:04 -0700206 buffer->unlock();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700207 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800208 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800209}
210
211
212void Layer::onDraw(const Region& clip) const
213{
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700214 const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ?
215 mFrontBufferIndex : 0;
216 GLuint textureName = mTextures[index].name;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700217 if (UNLIKELY(textureName == -1LU)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800218 // the texture has not been created yet, this Layer has
219 // in fact never been drawn into. this happens frequently with
220 // SurfaceView.
221 clearWithOpenGL(clip);
222 return;
223 }
Mathias Agopian1fed11c2009-06-23 18:08:22 -0700224 drawWithOpenGL(clip, mTextures[index]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800225}
226
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700227sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800228{
Mathias Agopian48d819a2009-09-10 19:41:18 -0700229 sp<Buffer> buffer;
230
231 // this ensures our client doesn't go away while we're accessing
232 // the shared area.
233 sp<Client> ourClient(client.promote());
234 if (ourClient == 0) {
235 // oops, the client is already gone
236 return buffer;
237 }
238
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700239 /*
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700240 * This is called from the client's Surface::dequeue(). This can happen
241 * at any time, especially while we're in the middle of using the
242 * buffer 'index' as our front buffer.
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700243 *
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700244 * Make sure the buffer we're resizing is not the front buffer and has been
245 * dequeued. Once this condition is asserted, we are guaranteed that this
246 * buffer cannot become the front buffer under our feet, since we're called
247 * from Surface::dequeue()
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700248 */
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700249 status_t err = lcblk->assertReallocate(index);
250 LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
Mathias Agopian48d819a2009-09-10 19:41:18 -0700251 if (err != NO_ERROR) {
252 // the surface may have died
253 return buffer;
254 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800255
Mathias Agopian48d819a2009-09-10 19:41:18 -0700256 uint32_t w, h;
257 { // scope for the lock
258 Mutex::Autolock _l(mLock);
259 w = mWidth;
260 h = mHeight;
261 buffer = mBuffers[index];
Mathias Agopian6d9f6982009-09-17 19:19:08 -0700262
263 // destroy() could have been called before we get here, we log it
264 // because it's uncommon, and the code below should handle it
265 LOGW_IF(buffer==0,
266 "mBuffers[%d] is null (mWidth=%d, mHeight=%d)",
267 index, w, h);
268
Mathias Agopian48d819a2009-09-10 19:41:18 -0700269 mBuffers[index].clear();
270 }
271
Mathias Agopian6d9f6982009-09-17 19:19:08 -0700272 if (buffer!=0 && buffer->getStrongCount() == 1) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700273 err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700274 } else {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700275 // here we have to reallocate a new buffer because we could have a
276 // client in our process with a reference to it (eg: status bar),
277 // and we can't release the handle under its feet.
278 buffer.clear();
279 buffer = new Buffer(w, h, mFormat, usage, mBufferFlags);
280 err = buffer->initCheck();
281 }
282
283 if (err || buffer->handle == 0) {
284 LOGE_IF(err || buffer->handle == 0,
285 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
286 this, index, w, h, strerror(-err));
287 } else {
288 LOGD_IF(DEBUG_RESIZE,
Mathias Agopian7e4a5872009-09-29 22:39:22 -0700289 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
290 this, index, w, h, buffer->handle);
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700291 }
292
293 if (err == NO_ERROR && buffer->handle != 0) {
Mathias Agopian48d819a2009-09-10 19:41:18 -0700294 Mutex::Autolock _l(mLock);
295 if (mWidth && mHeight) {
296 // and we have new buffer
297 mBuffers[index] = buffer;
298 // texture is now dirty...
299 mTextures[index].dirty = true;
300 } else {
301 // oops we got killed while we were allocating the buffer
302 buffer.clear();
303 }
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700304 }
305 return buffer;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800306}
307
308uint32_t Layer::doTransaction(uint32_t flags)
309{
310 const Layer::State& front(drawingState());
311 const Layer::State& temp(currentState());
312
Mathias Agopian7e4a5872009-09-29 22:39:22 -0700313 if ((front.requested_w != temp.requested_w) ||
314 (front.requested_h != temp.requested_h)) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700315 // the size changed, we need to ask our client to request a new buffer
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800316 LOGD_IF(DEBUG_RESIZE,
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700317 "resize (layer=%p), requested (%dx%d), "
318 "drawing (%d,%d), (%dx%d), (%dx%d)",
Mathias Agopian7e4a5872009-09-29 22:39:22 -0700319 this,
320 int(temp.requested_w), int(temp.requested_h),
321 int(front.requested_w), int(front.requested_h),
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700322 int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
323 int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800324
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700325 // we're being resized and there is a freeze display request,
326 // acquire a freeze lock, so that the screen stays put
327 // until we've redrawn at the new size; this is to avoid
328 // glitches upon orientation changes.
329 if (mFlinger->hasFreezeRequest()) {
330 // if the surface is hidden, don't try to acquire the
331 // freeze lock, since hidden surfaces may never redraw
332 if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
333 mFreezeLock = mFlinger->getFreezeLock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800334 }
335 }
Mathias Agopiancaa600c2009-09-16 18:27:24 -0700336
Mathias Agopiandf3e0b92009-09-30 14:07:22 -0700337 // this will make sure LayerBase::doTransaction doesn't update
338 // the drawing state's size
339 Layer::State& editDraw(mDrawingState);
340 editDraw.requested_w = temp.requested_w;
341 editDraw.requested_h = temp.requested_h;
342
Mathias Agopian6656dbc2009-09-30 12:48:47 -0700343 // record the new size, form this point on, when the client request a
344 // buffer, it'll get the new size.
345 setDrawingSize(temp.requested_w, temp.requested_h);
346
Mathias Agopiancaa600c2009-09-16 18:27:24 -0700347 // all buffers need reallocation
348 lcblk->reallocate();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800349 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700350
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800351 if (temp.sequence != front.sequence) {
352 if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
353 // this surface is now hidden, so it shouldn't hold a freeze lock
354 // (it may never redraw, which is fine if it is hidden)
355 mFreezeLock.clear();
356 }
357 }
358
359 return LayerBase::doTransaction(flags);
360}
361
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700362void Layer::setDrawingSize(uint32_t w, uint32_t h) {
363 Mutex::Autolock _l(mLock);
364 mWidth = w;
365 mHeight = h;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800366}
367
368// ----------------------------------------------------------------------------
369// pageflip handling...
370// ----------------------------------------------------------------------------
371
372void Layer::lockPageFlip(bool& recomputeVisibleRegions)
373{
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700374 ssize_t buf = lcblk->retireAndLock();
375 if (buf < NO_ERROR) {
376 //LOGW("nothing to retire (%s)", strerror(-buf));
377 // NOTE: here the buffer is locked because we will used
378 // for composition later in the loop
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800379 return;
380 }
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700381
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700382 // we retired a buffer, which becomes the new front buffer
383 mFrontBufferIndex = buf;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800384
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700385 // get the dirty region
386 sp<Buffer> newFrontBuffer(getBuffer(buf));
387 const Region dirty(lcblk->getDirtyRegion(buf));
388 mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700389
Mathias Agopiancaa600c2009-09-16 18:27:24 -0700390 const Layer::State& front(drawingState());
Mathias Agopiandf3e0b92009-09-30 14:07:22 -0700391 if (newFrontBuffer->getWidth() == front.requested_w &&
392 newFrontBuffer->getHeight() == front.requested_h)
393 {
394 if ((front.w != front.requested_w) ||
395 (front.h != front.requested_h))
396 {
397 // Here we pretend the transaction happened by updating the
398 // current and drawing states. Drawing state is only accessed
399 // in this thread, no need to have it locked
400 Layer::State& editDraw(mDrawingState);
401 editDraw.w = editDraw.requested_w;
402 editDraw.h = editDraw.requested_h;
403
404 // We also need to update the current state so that we don't
405 // end-up doing too much work during the next transaction.
406 // NOTE: We actually don't need hold the transaction lock here
407 // because State::w and State::h are only accessed from
408 // this thread
409 Layer::State& editTemp(currentState());
410 editTemp.w = editDraw.w;
411 editTemp.h = editDraw.h;
412
413 // recompute visible region
414 recomputeVisibleRegions = true;
415
416 // we now have the correct size, unfreeze the screen
417 mFreezeLock.clear();
418 }
Mathias Agopiancaa600c2009-09-16 18:27:24 -0700419 }
420
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700421 // FIXME: signal an event if we have more buffers waiting
422 // mFlinger->signalEvent();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800423
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700424 reloadTexture( mPostedDirtyRegion );
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800425}
426
427void Layer::unlockPageFlip(
428 const Transform& planeTransform, Region& outDirtyRegion)
429{
430 Region dirtyRegion(mPostedDirtyRegion);
431 if (!dirtyRegion.isEmpty()) {
432 mPostedDirtyRegion.clear();
433 // The dirty region is given in the layer's coordinate space
434 // transform the dirty region by the surface's transformation
435 // and the global transformation.
436 const Layer::State& s(drawingState());
437 const Transform tr(planeTransform * s.transform);
438 dirtyRegion = tr.transform(dirtyRegion);
439
440 // At this point, the dirty region is in screen space.
441 // Make sure it's constrained by the visible region (which
442 // is in screen space as well).
443 dirtyRegion.andSelf(visibleRegionScreen);
444 outDirtyRegion.orSelf(dirtyRegion);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800445 }
446}
447
448void Layer::finishPageFlip()
449{
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700450 status_t err = lcblk->unlock( mFrontBufferIndex );
451 LOGE_IF(err!=NO_ERROR,
452 "layer %p, buffer=%d wasn't locked!",
453 this, mFrontBufferIndex);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800454}
455
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700456// ---------------------------------------------------------------------------
457
Mathias Agopian9a112062009-04-17 19:36:26 -0700458Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
459 SurfaceID id, const sp<Layer>& owner)
460 : Surface(flinger, id, owner->getIdentity(), owner)
461{
462}
463
464Layer::SurfaceLayer::~SurfaceLayer()
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700465{
466}
467
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700468sp<SurfaceBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700469{
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700470 sp<SurfaceBuffer> buffer;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700471 sp<Layer> owner(getOwner());
472 if (owner != 0) {
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700473 LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
474 "getBuffer() index (%d) out of range", index);
475 if (uint32_t(index) < NUM_BUFFERS) {
476 buffer = owner->requestBuffer(index, usage);
477 }
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700478 }
479 return buffer;
480}
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800481
482// ---------------------------------------------------------------------------
483
484
485}; // namespace android