diff options
-rw-r--r-- | core/java/android/app/Activity.java | 7 | ||||
-rw-r--r-- | include/private/surfaceflinger/SharedBufferStack.h | 18 | ||||
-rw-r--r-- | include/surfaceflinger/Surface.h | 3 | ||||
-rw-r--r-- | include/ui/egl/android_natives.h | 29 | ||||
-rw-r--r-- | libs/surfaceflinger_client/SharedBufferStack.cpp | 46 | ||||
-rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 22 | ||||
-rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 22 | ||||
-rw-r--r-- | media/libstagefright/include/ARTSPController.h | 2 | ||||
-rw-r--r-- | media/libstagefright/include/AwesomePlayer.h | 1 | ||||
-rw-r--r-- | media/libstagefright/rtsp/APacketSource.cpp | 52 | ||||
-rw-r--r-- | media/libstagefright/rtsp/APacketSource.h | 5 | ||||
-rw-r--r-- | media/libstagefright/rtsp/ARTSPController.cpp | 12 | ||||
-rw-r--r-- | media/libstagefright/rtsp/MyHandler.h | 109 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.cpp | 107 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBlur.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBuffer.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/TextureManager.h | 3 |
19 files changed, 363 insertions, 96 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index f7ccc12..ed5af91 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -3898,7 +3898,14 @@ public class Activity extends ContextThemeWrapper } final void performPause() { + mCalled = false; onPause(); + if (!mCalled && getApplicationInfo().targetSdkVersion + >= android.os.Build.VERSION_CODES.GINGERBREAD) { + throw new SuperNotCalledException( + "Activity " + mComponent.toShortString() + + " did not call through to super.onPause()"); + } } final void performUserLeaving() { diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h index 1eb178e..d016dfa 100644 --- a/include/private/surfaceflinger/SharedBufferStack.h +++ b/include/private/surfaceflinger/SharedBufferStack.h @@ -54,11 +54,6 @@ class SharedClient; // ---------------------------------------------------------------------------- -// 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX -// 4 * (11 + 7 + (1 + 2*7)*16) * 31 -// 1032 * 31 -// = ~27 KiB (31992) - class SharedBufferStack { friend class SharedClient; @@ -85,7 +80,7 @@ public: }; struct FlatRegion { // 52 bytes = 4 * (1 + 2*N) - static const unsigned int NUM_RECT_MAX = 6; + static const unsigned int NUM_RECT_MAX = 5; uint32_t count; SmallRect rects[NUM_RECT_MAX]; }; @@ -93,13 +88,18 @@ public: struct BufferData { FlatRegion dirtyRegion; SmallRect crop; + uint8_t transform; + uint8_t reserved[3]; }; SharedBufferStack(); void init(int32_t identity); status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); + status_t setTransform(int buffer, uint8_t transform); Region getDirtyRegion(int buffer) const; + Rect getCrop(int buffer) const; + uint32_t getTransform(int buffer) const; // these attributes are part of the conditions/updates volatile int32_t head; // server's current front buffer @@ -117,7 +117,7 @@ public: int32_t reserved32[1]; Statistics stats; int32_t reserved; - BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes + BufferData buffers[NUM_BUFFER_MAX]; // 1024 bytes }; // ---------------------------------------------------------------------------- @@ -206,7 +206,7 @@ public: bool needNewBuffer(int buffer) const; status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); - + status_t setTransform(int buffer, uint32_t transform); class SetBufferCountCallback { friend class SharedBufferClient; @@ -275,6 +275,8 @@ public: status_t reallocateAllExcept(int buffer); int32_t getQueuedCount() const; Region getDirtyRegion(int buffer) const; + Rect getCrop(int buffer) const; + uint32_t getTransform(int buffer) const; status_t resize(int newNumBuffers); diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index 294c867..7c5a39b 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -216,6 +216,7 @@ private: int dispatch_crop(va_list args); int dispatch_set_buffer_count(va_list args); int dispatch_set_buffers_geometry(va_list args); + int dispatch_set_buffers_transform(va_list args); void setUsage(uint32_t reqUsage); int connect(int api); @@ -223,6 +224,7 @@ private: int crop(Rect const* rect); int setBufferCount(int bufferCount); int setBuffersGeometry(int w, int h, int format); + int setBuffersTransform(int transform); /* * private stuff... @@ -278,6 +280,7 @@ private: Rect mSwapRectangle; int mConnected; Rect mNextBufferCrop; + uint32_t mNextBufferTransform; BufferInfo mBufferInfo; // protected by mSurfaceLock. These are also used from lock/unlock diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index ca89b06..d59d72b 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -85,6 +85,7 @@ enum { NATIVE_WINDOW_SET_CROP, NATIVE_WINDOW_SET_BUFFER_COUNT, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, + NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, }; /* parameter for NATIVE_WINDOW_[DIS]CONNECT */ @@ -92,6 +93,20 @@ enum { NATIVE_WINDOW_API_EGL = 1 }; +/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */ +enum { + /* flip source image horizontally */ + NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H , + /* flip source image vertically */ + NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, + /* rotate source image 90 degrees clock-wise */ + NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, + /* rotate source image 180 degrees */ + NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, + /* rotate source image 270 degrees clock-wise */ + NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, +}; + struct ANativeWindow { #ifdef __cplusplus @@ -196,6 +211,7 @@ struct ANativeWindow * NATIVE_WINDOW_SET_CROP * NATIVE_WINDOW_SET_BUFFER_COUNT * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY + * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM * */ @@ -298,6 +314,19 @@ static inline int native_window_set_buffers_geometry( w, h, format); } +/* + * native_window_set_buffers_transform(..., int transform) + * All buffers queued after this call will be displayed transformed according + * to the transform parameter specified. + */ +static inline int native_window_set_buffers_transform( + ANativeWindow* window, + int transform) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, + transform); +} + // --------------------------------------------------------------------------- /* FIXME: this is legacy for pixmaps */ diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp index 156a7db..4ad9f86 100644 --- a/libs/surfaceflinger_client/SharedBufferStack.cpp +++ b/libs/surfaceflinger_client/SharedBufferStack.cpp @@ -75,6 +75,14 @@ status_t SharedBufferStack::setCrop(int buffer, const Rect& crop) return NO_ERROR; } +status_t SharedBufferStack::setTransform(int buffer, uint8_t transform) +{ + if (uint32_t(buffer) >= NUM_BUFFER_MAX) + return BAD_INDEX; + buffers[buffer].transform = transform; + return NO_ERROR; +} + status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) @@ -137,6 +145,26 @@ Region SharedBufferStack::getDirtyRegion(int buffer) const return res; } +Rect SharedBufferStack::getCrop(int buffer) const +{ + Rect res(-1, -1); + if (uint32_t(buffer) >= NUM_BUFFER_MAX) + return res; + res.left = buffers[buffer].crop.l; + res.top = buffers[buffer].crop.t; + res.right = buffers[buffer].crop.r; + res.bottom = buffers[buffer].crop.b; + return res; +} + +uint32_t SharedBufferStack::getTransform(int buffer) const +{ + if (uint32_t(buffer) >= NUM_BUFFER_MAX) + return 0; + return buffers[buffer].transform; +} + + // ---------------------------------------------------------------------------- SharedBufferBase::SharedBufferBase(SharedClient* sharedClient, @@ -433,6 +461,12 @@ status_t SharedBufferClient::setCrop(int buf, const Rect& crop) return stack.setCrop(buf, crop); } +status_t SharedBufferClient::setTransform(int buf, uint32_t transform) +{ + SharedBufferStack& stack( *mSharedStack ); + return stack.setTransform(buf, uint8_t(transform)); +} + status_t SharedBufferClient::setDirtyRegion(int buf, const Region& reg) { SharedBufferStack& stack( *mSharedStack ); @@ -549,6 +583,18 @@ Region SharedBufferServer::getDirtyRegion(int buf) const return stack.getDirtyRegion(buf); } +Rect SharedBufferServer::getCrop(int buf) const +{ + SharedBufferStack& stack( *mSharedStack ); + return stack.getCrop(buf); +} + +uint32_t SharedBufferServer::getTransform(int buf) const +{ + SharedBufferStack& stack( *mSharedStack ); + return stack.getTransform(buf); +} + /* * NOTE: this is not thread-safe on the server-side, meaning * 'head' cannot move during this operation. The client-side diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index 5ab72cd..cb76091 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -422,8 +422,10 @@ void Surface::init() const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; const_cast<uint32_t&>(ANativeWindow::flags) = 0; + mNextBufferTransform = 0; mConnected = 0; mSwapRectangle.makeInvalid(); + mNextBufferCrop = Rect(0,0); // two buffers by default mBuffers.setCapacity(2); mBuffers.insertAt(0, 2); @@ -631,6 +633,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) } int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer)); + mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform); mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop); mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion); err = mSharedBufferClient->queue(bufIdx); @@ -685,6 +688,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: res = dispatch_set_buffers_geometry( args ); break; + case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: + res = dispatch_set_buffers_transform( args ); + break; default: res = NAME_NOT_FOUND; break; @@ -719,6 +725,11 @@ int Surface::dispatch_set_buffers_geometry(va_list args) { return setBuffersGeometry(w, h, f); } +int Surface::dispatch_set_buffers_transform(va_list args) { + int transform = va_arg(args, int); + return setBuffersTransform(transform); +} + void Surface::setUsage(uint32_t reqUsage) { Mutex::Autolock _l(mSurfaceLock); @@ -765,6 +776,10 @@ int Surface::disconnect(int api) int Surface::crop(Rect const* rect) { + // empty/invalid rects are not allowed + if (rect->isEmpty()) + return BAD_VALUE; + Mutex::Autolock _l(mSurfaceLock); // TODO: validate rect size mNextBufferCrop = *rect; @@ -804,6 +819,13 @@ int Surface::setBuffersGeometry(int w, int h, int format) return NO_ERROR; } +int Surface::setBuffersTransform(int transform) +{ + Mutex::Autolock _l(mSurfaceLock); + mNextBufferTransform = transform; + return NO_ERROR; +} + // ---------------------------------------------------------------------------- int Surface::getConnectedApi() const diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index f2653cf..11fdf56 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -196,6 +196,7 @@ AwesomePlayer::AwesomePlayer() mExtractorFlags(0), mLastVideoBuffer(NULL), mVideoBuffer(NULL), + mRTSPTimeOffset(0), mSuspensionState(NULL) { CHECK_EQ(mClient.connect(), OK); @@ -393,7 +394,11 @@ void AwesomePlayer::reset_l() { mVideoBuffer = NULL; } - mRTSPController.clear(); + if (mRTSPController != NULL) { + mRTSPController->disconnect(); + mRTSPController.clear(); + } + mRTPPusher.clear(); mRTCPPusher.clear(); mRTPSession.clear(); @@ -738,6 +743,10 @@ status_t AwesomePlayer::getPosition(int64_t *positionUs) { *positionUs = 0; } + if (mRTSPController != NULL) { + *positionUs += mRTSPTimeOffset; + } + return OK; } @@ -753,6 +762,17 @@ status_t AwesomePlayer::seekTo(int64_t timeUs) { } status_t AwesomePlayer::seekTo_l(int64_t timeUs) { + if (mRTSPController != NULL) { + pause_l(); + mRTSPController->seek(timeUs); + play_l(); + + notifyListener_l(MEDIA_SEEK_COMPLETE); + mSeekNotificationSent = true; + mRTSPTimeOffset = timeUs; + return OK; + } + if (mFlags & CACHE_UNDERRUN) { mFlags &= ~CACHE_UNDERRUN; play_l(); diff --git a/media/libstagefright/include/ARTSPController.h b/media/libstagefright/include/ARTSPController.h index 2542e4e..7020564 100644 --- a/media/libstagefright/include/ARTSPController.h +++ b/media/libstagefright/include/ARTSPController.h @@ -33,6 +33,8 @@ struct ARTSPController : public MediaExtractor { status_t connect(const char *url); void disconnect(); + void seek(int64_t timeUs); + virtual size_t countTracks(); virtual sp<MediaSource> getTrack(size_t index); diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 55e2c36..49b5c78 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -180,6 +180,7 @@ private: sp<ALooper> mLooper; sp<ARTSPController> mRTSPController; + int64_t mRTSPTimeOffset; sp<ARTPSession> mRTPSession; sp<UDPPusher> mRTPPusher, mRTCPPusher; diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp index 8c56cb7..b930184 100644 --- a/media/libstagefright/rtsp/APacketSource.cpp +++ b/media/libstagefright/rtsp/APacketSource.cpp @@ -406,9 +406,7 @@ APacketSource::APacketSource( const sp<ASessionDescription> &sessionDesc, size_t index) : mInitCheck(NO_INIT), mFormat(new MetaData), - mEOSResult(OK), - mFirstAccessUnit(true), - mFirstAccessUnitNTP(0) { + mEOSResult(OK) { unsigned long PT; AString desc; AString params; @@ -550,9 +548,6 @@ status_t APacketSource::initCheck() const { } status_t APacketSource::start(MetaData *params) { - mFirstAccessUnit = true; - mFirstAccessUnitNTP = 0; - return OK; } @@ -600,25 +595,6 @@ void APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) { return; } - uint64_t ntpTime; - CHECK(buffer->meta()->findInt64( - "ntp-time", (int64_t *)&ntpTime)); - - if (mFirstAccessUnit) { - mFirstAccessUnit = false; - mFirstAccessUnitNTP = ntpTime; - } - - if (ntpTime > mFirstAccessUnitNTP) { - ntpTime -= mFirstAccessUnitNTP; - } else { - ntpTime = 0; - } - - int64_t timeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); - - buffer->meta()->setInt64("timeUs", timeUs); - Mutex::Autolock autoLock(mLock); mBuffers.push_back(buffer); mCondition.signal(); @@ -632,31 +608,9 @@ void APacketSource::signalEOS(status_t result) { mCondition.signal(); } -int64_t APacketSource::getQueuedDuration(bool *eos) { +void APacketSource::flushQueue() { Mutex::Autolock autoLock(mLock); - - *eos = (mEOSResult != OK); - - if (mBuffers.empty()) { - return 0; - } - - sp<ABuffer> buffer = *mBuffers.begin(); - - uint64_t ntpTime; - CHECK(buffer->meta()->findInt64( - "ntp-time", (int64_t *)&ntpTime)); - - int64_t firstTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); - - buffer = *--mBuffers.end(); - - CHECK(buffer->meta()->findInt64( - "ntp-time", (int64_t *)&ntpTime)); - - int64_t lastTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); - - return lastTimeUs - firstTimeUs; + mBuffers.clear(); } } // namespace android diff --git a/media/libstagefright/rtsp/APacketSource.h b/media/libstagefright/rtsp/APacketSource.h index 647da6e..197af3e 100644 --- a/media/libstagefright/rtsp/APacketSource.h +++ b/media/libstagefright/rtsp/APacketSource.h @@ -43,7 +43,7 @@ struct APacketSource : public MediaSource { void queueAccessUnit(const sp<ABuffer> &buffer); void signalEOS(status_t result); - int64_t getQueuedDuration(bool *eos); + void flushQueue(); protected: virtual ~APacketSource(); @@ -58,9 +58,6 @@ private: List<sp<ABuffer> > mBuffers; status_t mEOSResult; - bool mFirstAccessUnit; - uint64_t mFirstAccessUnitNTP; - DISALLOW_EVIL_CONSTRUCTORS(APacketSource); }; diff --git a/media/libstagefright/rtsp/ARTSPController.cpp b/media/libstagefright/rtsp/ARTSPController.cpp index ceae3a6..9df17cb 100644 --- a/media/libstagefright/rtsp/ARTSPController.cpp +++ b/media/libstagefright/rtsp/ARTSPController.cpp @@ -33,7 +33,7 @@ ARTSPController::ARTSPController(const sp<ALooper> &looper) } ARTSPController::~ARTSPController() { - disconnect(); + CHECK_EQ((int)mState, (int)DISCONNECTED); mLooper->unregisterHandler(mReflector->id()); } @@ -80,6 +80,16 @@ void ARTSPController::disconnect() { mHandler.clear(); } +void ARTSPController::seek(int64_t timeUs) { + Mutex::Autolock autoLock(mLock); + + if (mState != CONNECTED) { + return; + } + + mHandler->seek(timeUs); +} + size_t ARTSPController::countTracks() { if (mHandler == NULL) { return 0; diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 90070c9..e248463 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -38,7 +38,10 @@ struct MyHandler : public AHandler { mConn(new ARTSPConnection), mRTPConn(new ARTPConnection), mSessionURL(url), - mSetupTracksSuccessful(false) { + mSetupTracksSuccessful(false), + mSeekPending(false), + mFirstAccessUnit(true), + mFirstAccessUnitNTP(0) { mNetLooper->start(false /* runOnCallingThread */, false /* canCallJava */, @@ -62,6 +65,12 @@ struct MyHandler : public AHandler { (new AMessage('abor', id()))->post(); } + void seek(int64_t timeUs) { + sp<AMessage> msg = new AMessage('seek', id()); + msg->setInt64("time", timeUs); + msg->post(); + } + virtual void onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case 'conn': @@ -88,8 +97,6 @@ struct MyHandler : public AHandler { case 'disc': { - LOG(INFO) << "disconnect completed"; - (new AMessage('quit', id()))->post(); break; } @@ -337,7 +344,20 @@ struct MyHandler : public AHandler { CHECK(accessUnit->meta()->findInt64( "ntp-time", (int64_t *)&ntpTime)); - accessUnit->meta()->setInt64("ntp-time", ntpTime); + if (mFirstAccessUnit) { + mFirstAccessUnit = false; + mFirstAccessUnitNTP = ntpTime; + } + + if (ntpTime >= mFirstAccessUnitNTP) { + ntpTime -= mFirstAccessUnitNTP; + } else { + ntpTime = 0; + } + + int64_t timeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); + + accessUnit->meta()->setInt64("timeUs", timeUs); #if 0 int32_t damaged; @@ -353,6 +373,84 @@ struct MyHandler : public AHandler { break; } + case 'seek': + { + if (mSeekPending) { + break; + } + + int64_t timeUs; + CHECK(msg->findInt64("time", &timeUs)); + + mSeekPending = true; + + AString request = "PAUSE "; + request.append(mSessionURL); + request.append(" RTSP/1.0\r\n"); + + request.append("Session: "); + request.append(mSessionID); + request.append("\r\n"); + + request.append("\r\n"); + + sp<AMessage> reply = new AMessage('see1', id()); + reply->setInt64("time", timeUs); + mConn->sendRequest(request.c_str(), reply); + break; + } + + case 'see1': + { + int64_t timeUs; + CHECK(msg->findInt64("time", &timeUs)); + + AString request = "PLAY "; + request.append(mSessionURL); + request.append(" RTSP/1.0\r\n"); + + request.append("Session: "); + request.append(mSessionID); + request.append("\r\n"); + + request.append( + StringPrintf( + "Range: npt=%lld-\r\n", timeUs / 1000000ll)); + + request.append("\r\n"); + + sp<AMessage> reply = new AMessage('see2', id()); + mConn->sendRequest(request.c_str(), reply); + break; + } + + case 'see2': + { + CHECK(mSeekPending); + + LOG(INFO) << "seek completed."; + mSeekPending = false; + + int32_t result; + CHECK(msg->findInt32("result", &result)); + if (result != OK) { + LOG(ERROR) << "seek FAILED"; + break; + } + + sp<RefBase> obj; + CHECK(msg->findObject("response", &obj)); + sp<ARTSPResponse> response = + static_cast<ARTSPResponse *>(obj.get()); + + CHECK_EQ(response->mStatusCode, 200u); + + for (size_t i = 0; i < mTracks.size(); ++i) { + mTracks.editItemAt(i).mPacketSource->flushQueue(); + } + break; + } + default: TRESPASS(); break; @@ -380,6 +478,9 @@ private: AString mBaseURL; AString mSessionID; bool mSetupTracksSuccessful; + bool mSeekPending; + bool mFirstAccessUnit; + uint64_t mFirstAccessUnitNTP; struct TrackInfo { int mRTPSocket; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 629d993..6f3c66d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -473,9 +473,9 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) return; } - // get the dirty region sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); if (newFrontBuffer != NULL) { + // get the dirty region // compute the posted region const Region dirty(lcblk->getDirtyRegion(buf)); mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); @@ -511,6 +511,13 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) // we now have the correct size, unfreeze the screen mFreezeLock.clear(); } + + // get the crop region + setBufferCrop( lcblk->getCrop(buf) ); + + // get the transformation + setBufferTransform( lcblk->getTransform(buf) ); + } else { // this should not happen unless we ran out of memory while // allocating the buffer. we're hoping that things will get back diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index 91ac915..6fc5010 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -54,6 +54,8 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) { const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); mFlags = hw.getFlags(); + mBufferCrop.makeInvalid(); + mBufferTransform = 0; } LayerBase::~LayerBase() @@ -345,6 +347,14 @@ void LayerBase::clearWithOpenGL(const Region& clip) const clearWithOpenGL(clip,0,0,0,0); } +template <typename T> +static inline +void swap(T& a, T& b) { + T t(a); + a = b; + b = t; +} + void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); @@ -378,38 +388,73 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const } } - Region::const_iterator it = clip.begin(); - Region::const_iterator const end = clip.end(); - const GLfloat texCoords[4][2] = { - { 0, 0 }, - { 0, 1 }, - { 1, 1 }, - { 1, 0 } + /* + * compute texture coordinates + * here, we handle NPOT, cropping and buffer transformations + */ + + GLfloat cl, ct, cr, cb; + if (!mBufferCrop.isEmpty()) { + // source is cropped + const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width; + const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height; + cl = mBufferCrop.left * us; + ct = mBufferCrop.top * vs; + cr = mBufferCrop.right * us; + cb = mBufferCrop.bottom * vs; + } else { + cl = 0; + ct = 0; + cr = (texture.NPOTAdjust ? texture.wScale : 1.0f); + cb = (texture.NPOTAdjust ? texture.hScale : 1.0f); + } + + struct TexCoords { + GLfloat u; + GLfloat v; + }; + + enum { + // name of the corners in the texture map + LB = 0, // left-bottom + LT = 1, // left-top + RT = 2, // right-top + RB = 3 // right-bottom }; - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); + // vertices in screen space + int vLT = LB; + int vLB = LT; + int vRB = RT; + int vRT = RB; // the texture's source is rotated - switch (texture.transform) { - case HAL_TRANSFORM_ROT_90: - glTranslatef(0, 1, 0); - glRotatef(-90, 0, 0, 1); - break; - case HAL_TRANSFORM_ROT_180: - glTranslatef(1, 1, 0); - glRotatef(-180, 0, 0, 1); - break; - case HAL_TRANSFORM_ROT_270: - glTranslatef(1, 0, 0); - glRotatef(-270, 0, 0, 1); - break; + uint32_t transform = mBufferTransform; + if (transform & HAL_TRANSFORM_ROT_90) { + vLT = RB; + vLB = LB; + vRB = LT; + vRT = RT; } - - if (texture.NPOTAdjust) { - glScalef(texture.wScale, texture.hScale, 1.0f); + if (transform & HAL_TRANSFORM_FLIP_V) { + swap(vLT, vLB); + swap(vRB, vRT); + } + if (transform & HAL_TRANSFORM_FLIP_H) { + swap(vLT, vRB); + swap(vLB, vRT); } + TexCoords texCoords[4]; + texCoords[vLT].u = cl; + texCoords[vLT].v = ct; + texCoords[vLB].u = cl; + texCoords[vLB].v = cb; + texCoords[vRB].u = cr; + texCoords[vRB].v = cb; + texCoords[vRT].u = cr; + texCoords[vRT].v = ct; + if (needsDithering()) { glEnable(GL_DITHER); } else { @@ -420,6 +465,8 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + Region::const_iterator it = clip.begin(); + Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); @@ -429,6 +476,16 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glDisableClientState(GL_TEXTURE_COORD_ARRAY); } +void LayerBase::setBufferCrop(const Rect& crop) { + if (!crop.isEmpty()) { + mBufferCrop = crop; + } +} + +void LayerBase::setBufferTransform(uint32_t transform) { + mBufferTransform = transform; +} + void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const { const Layer::State& s(drawingState()); diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index 22bf857..8cba287 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -226,9 +226,17 @@ protected: void clearWithOpenGL(const Region& clip) const; void drawWithOpenGL(const Region& clip, const Texture& texture) const; + // these must be called from the post/drawing thread + void setBufferCrop(const Rect& crop); + void setBufferTransform(uint32_t transform); + sp<SurfaceFlinger> mFlinger; uint32_t mFlags; + // post/drawing thread + Rect mBufferCrop; + uint32_t mBufferTransform; + // cached during validateVisibility() bool mNeedsFiltering; int32_t mOrientation; diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp index 64a43c7..2ee21b9 100644 --- a/services/surfaceflinger/LayerBlur.cpp +++ b/services/surfaceflinger/LayerBlur.cpp @@ -241,6 +241,8 @@ void LayerBlur::onDraw(const Region& clip) const glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); } } diff --git a/services/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp index 5f83636..0240748 100644 --- a/services/surfaceflinger/LayerBuffer.cpp +++ b/services/surfaceflinger/LayerBuffer.cpp @@ -485,7 +485,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const mTextureManager.loadTexture(&mTexture, dirty, t); } - mTexture.transform = mBufferHeap.transform; + mLayer.setBufferTransform(mBufferHeap.transform); mLayer.drawWithOpenGL(clip, mTexture); } diff --git a/services/surfaceflinger/TextureManager.h b/services/surfaceflinger/TextureManager.h index c7c14e7..18c4348 100644 --- a/services/surfaceflinger/TextureManager.h +++ b/services/surfaceflinger/TextureManager.h @@ -40,12 +40,11 @@ class GraphicBuffer; struct Image { enum { TEXTURE_2D=0, TEXTURE_EXTERNAL=1 }; Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0), - transform(0), dirty(1), target(TEXTURE_2D) { } + dirty(1), target(TEXTURE_2D) { } GLuint name; EGLImageKHR image; GLuint width; GLuint height; - uint32_t transform; unsigned dirty : 1; unsigned target : 1; }; |