diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 102 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 9 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 7 |
3 files changed, 46 insertions, 72 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index ea2c5d4..c6a9909 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -336,16 +336,9 @@ CameraService::Client::~Client() { int callingPid = getCallingPid(); LOG1("Client::~Client E (pid %d, this %p)", callingPid, this); - if (mSurface != 0 && !mUseOverlay) { - pthread_t thr; - // We unregister the buffers in a different thread because binder does - // not let us make sychronous transactions in a binder destructor (that - // is, upon our reaching a refcount of zero.) - pthread_create(&thr, - NULL, // attr - unregister_surface, - mSurface.get()); - pthread_join(thr, NULL); + // Clean up the ANativeWindow + if (mSurface != 0) { + setPreviewDisplay(0); } // set mClientPid to let disconnet() tear down the hardware @@ -465,6 +458,11 @@ void CameraService::Client::disconnect() { if (mUseOverlay) { mOverlayRef = 0; } + // Release the held ANativeWindow resources. + if (mPreviewWindow != 0) { + mPreviewWindow = 0; + mHardware->setPreviewWindow(mPreviewWindow); + } mHardware.clear(); mCameraService->removeClient(mCameraClient); @@ -475,8 +473,8 @@ void CameraService::Client::disconnect() { // ---------------------------------------------------------------------------- -// set the ISurface that the preview will use -status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { +// set the Surface that the preview will use +status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); Mutex::Autolock lock(mLock); status_t result = checkPidAndHardware(); @@ -486,7 +484,7 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { // return if no change in surface. // asBinder() is safe on NULL (returns NULL) - if (surface->asBinder() == mSurface->asBinder()) { + if (getISurface(surface)->asBinder() == mSurface->asBinder()) { return result; } @@ -496,44 +494,28 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { // Force the destruction of any previous overlay sp<Overlay> dummy; mHardware->setOverlay(dummy); - } else { - mSurface->unregisterBuffers(); } } - mSurface = surface; + if (surface != 0) { + mSurface = getISurface(surface); + } else { + mSurface = 0; + } + mPreviewWindow = surface; mOverlayRef = 0; // If preview has been already started, set overlay or register preview // buffers now. if (mHardware->previewEnabled()) { if (mUseOverlay) { result = setOverlay(); - } else if (mSurface != 0) { - result = registerPreviewBuffers(); + } else if (mPreviewWindow != 0) { + result = mHardware->setPreviewWindow(mPreviewWindow); } } return result; } -status_t CameraService::Client::registerPreviewBuffers() { - int w, h; - CameraParameters params(mHardware->getParameters()); - params.getPreviewSize(&w, &h); - - // FIXME: don't use a hardcoded format here. - ISurface::BufferHeap buffers(w, h, w, h, - HAL_PIXEL_FORMAT_YCrCb_420_SP, - mOrientation, - 0, - mHardware->getPreviewHeap()); - - status_t result = mSurface->registerBuffers(buffers); - if (result != NO_ERROR) { - LOGE("registerBuffers failed with status %d", result); - } - return result; -} - status_t CameraService::Client::setOverlay() { int w, h; CameraParameters params(mHardware->getParameters()); @@ -624,14 +606,14 @@ status_t CameraService::Client::startCameraMode(camera_mode mode) { switch(mode) { case CAMERA_PREVIEW_MODE: - if (mSurface == 0) { + if (mSurface == 0 && mPreviewWindow == 0) { LOG1("mSurface is not set yet."); // still able to start preview in this case. } return startPreviewMode(); case CAMERA_RECORDING_MODE: - if (mSurface == 0) { - LOGE("mSurface must be set before startRecordingMode."); + if (mSurface == 0 && mPreviewWindow == 0) { + LOGE("mSurface or mPreviewWindow must be set before startRecordingMode."); return INVALID_OPERATION; } return startRecordingMode(); @@ -657,16 +639,10 @@ status_t CameraService::Client::startPreviewMode() { if (result != NO_ERROR) return result; result = mHardware->startPreview(); } else { + // XXX: Set the orientation of the ANativeWindow. + mHardware->setPreviewWindow(mPreviewWindow); enableMsgType(CAMERA_MSG_PREVIEW_FRAME); result = mHardware->startPreview(); - if (result != NO_ERROR) return result; - // If preview display has been set, register preview buffers now. - if (mSurface != 0) { - // Unregister here because the surface may be previously registered - // with the raw (snapshot) heap. - mSurface->unregisterBuffers(); - result = registerPreviewBuffers(); - } } return result; } @@ -704,13 +680,10 @@ void CameraService::Client::stopPreview() { Mutex::Autolock lock(mLock); if (checkPidAndHardware() != NO_ERROR) return; + disableMsgType(CAMERA_MSG_PREVIEW_FRAME); mHardware->stopPreview(); - if (mSurface != 0 && !mUseOverlay) { - mSurface->unregisterBuffers(); - } - mPreviewBuffer.clear(); } @@ -998,11 +971,6 @@ void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, void CameraService::Client::handleShutter(image_rect_type *size) { mCameraService->playSound(SOUND_SHUTTER); - // Screen goes black after the buffer is unregistered. - if (mSurface != 0 && !mUseOverlay) { - mSurface->unregisterBuffers(); - } - sp<ICameraClient> c = mCameraClient; if (c != 0) { mLock.unlock(); @@ -1030,7 +998,6 @@ void CameraService::Client::handleShutter(image_rect_type *size) { HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0, mHardware->getRawHeap()); - mSurface->registerBuffers(buffers); IPCThreadState::self()->flushCommands(); } @@ -1043,12 +1010,6 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - if (!mUseOverlay) { - if (mSurface != 0) { - mSurface->postBuffer(offset); - } - } - // local copy of the callback flags int flags = mPreviewCallbackFlag; @@ -1108,11 +1069,6 @@ void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) { size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - // Put the YUV version of the snapshot in the preview display. - if (mSurface != 0 && !mUseOverlay) { - mSurface->postBuffer(offset); - } - sp<ICameraClient> c = mCameraClient; mLock.unlock(); if (c != 0) { @@ -1270,4 +1226,12 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { return NO_ERROR; } +sp<ISurface> CameraService::getISurface(const sp<Surface>& surface) { + if (surface != 0) { + return surface->getISurface(); + } else { + return sp<ISurface>(0); + } +} + }; // namespace android diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 0d69836..7ed192e 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -79,6 +79,12 @@ private: sp<MediaPlayer> mSoundPlayer[NUM_SOUNDS]; int mSoundRef; // reference count (release all MediaPlayer when 0) + // Used by Client objects to extract the ISurface from a Surface object. + // This is used because making Client a friend class of Surface would + // require including this header in Surface.h since Client is a nested + // class. + static sp<ISurface> getISurface(const sp<Surface>& surface); + class Client : public BnCamera { public: @@ -87,7 +93,7 @@ private: virtual status_t connect(const sp<ICameraClient>& client); virtual status_t lock(); virtual status_t unlock(); - virtual status_t setPreviewDisplay(const sp<ISurface>& surface); + virtual status_t setPreviewDisplay(const sp<Surface>& surface); virtual void setPreviewCallbackFlag(int flag); virtual status_t startPreview(); virtual void stopPreview(); @@ -169,6 +175,7 @@ private: // Ensures atomicity among the public methods mutable Mutex mLock; sp<ISurface> mSurface; + sp<ANativeWindow> mPreviewWindow; // If the user want us to return a copy of the preview frame (instead // of the original one), we allocate mPreviewBuffer and reuse it if possible. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index af7c3bf..a78d9b9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1745,12 +1745,15 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const { int32_t name = NAME_NOT_FOUND; sp<Layer> layer(mFlinger->getLayer(sur)); - if (layer == 0) return name; + if (layer == 0) { + return name; + } // if this layer already has a token, just return it name = layer->getToken(); - if ((name >= 0) && (layer->getClient() == this)) + if ((name >= 0) && (layer->getClient() == this)) { return name; + } name = 0; do { |