summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:23 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:23 -0800
commit276293246ea9cbc0a578a7697cc48930376ec0e9 (patch)
tree03804488c60dda65699333d2311c8d1842ec4b65 /libs
parente09fd9e819c23dc90bca68375645e15544861330 (diff)
downloadframeworks_native-276293246ea9cbc0a578a7697cc48930376ec0e9.zip
frameworks_native-276293246ea9cbc0a578a7697cc48930376ec0e9.tar.gz
frameworks_native-276293246ea9cbc0a578a7697cc48930376ec0e9.tar.bz2
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'libs')
-rw-r--r--libs/audioflinger/A2dpAudioInterface.cpp49
-rw-r--r--libs/audioflinger/A2dpAudioInterface.h12
-rw-r--r--libs/audioflinger/AudioDumpInterface.cpp16
-rw-r--r--libs/audioflinger/AudioDumpInterface.h2
-rw-r--r--libs/audioflinger/AudioFlinger.cpp135
-rw-r--r--libs/audioflinger/AudioFlinger.h3
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.cpp12
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.h2
-rw-r--r--libs/audioflinger/AudioHardwareStub.cpp10
-rw-r--r--libs/audioflinger/AudioHardwareStub.h2
-rw-r--r--libs/surfaceflinger/BootAnimation.cpp4
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp4
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.h6
-rw-r--r--libs/surfaceflinger/Layer.cpp4
-rw-r--r--libs/surfaceflinger/LayerBase.cpp17
-rw-r--r--libs/surfaceflinger/LayerBase.h79
-rw-r--r--libs/surfaceflinger/LayerBlur.cpp2
-rw-r--r--libs/surfaceflinger/LayerBuffer.cpp617
-rw-r--r--libs/surfaceflinger/LayerBuffer.h134
-rw-r--r--libs/surfaceflinger/LayerScreenshot.cpp2
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp24
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.h14
-rw-r--r--libs/surfaceflinger/Transform.h2
-rw-r--r--libs/ui/Camera.cpp19
-rw-r--r--libs/ui/ICamera.cpp45
-rw-r--r--libs/ui/IOverlay.cpp15
-rw-r--r--libs/ui/ISurface.cpp8
-rw-r--r--libs/ui/Overlay.cpp122
-rw-r--r--libs/ui/Region.cpp2
-rw-r--r--libs/utils/MemoryHeapBase.cpp25
30 files changed, 881 insertions, 507 deletions
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index d54795c..b2a8e96 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -79,11 +79,6 @@ AudioStreamIn* A2dpAudioInterface::openInputStream(
return NULL;
}
-status_t A2dpAudioInterface::standby()
-{
- return 0;
-}
-
status_t A2dpAudioInterface::setMicMute(bool state)
{
return 0;
@@ -123,8 +118,8 @@ status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
// ----------------------------------------------------------------------------
A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
- mFd(-1), mStartCount(0), mRetryCount(0), mData(NULL),
- mInitialized(false), mBufferRemaining(0)
+ mFd(-1), mStandby(false), mStartCount(0), mRetryCount(0), mData(NULL),
+ mInitialized(false)
{
}
@@ -155,26 +150,50 @@ A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
{
+ status_t status = NO_INIT;
+ size_t remaining = bytes;
+
if (!mInitialized) {
- int ret = a2dp_init("00:00:00:00:00:00", 44100, 2, &mData);
- if (ret)
- return ret;
+ status = a2dp_init("00:00:00:00:00:00", 44100, 2, &mData);
+ if (status < 0) {
+ LOGE("a2dp_init failed err: %d\n", status);
+ goto Error;
+ }
mInitialized = true;
}
- size_t remaining = bytes;
while (remaining > 0) {
- int written = a2dp_write(mData, buffer, remaining);
- remaining -= written;
- buffer = ((char *)buffer) + written;
+ status = a2dp_write(mData, buffer, remaining);
+ if (status <= 0) {
+ LOGE("a2dp_write failed err: %d\n", status);
+ goto Error;
+ }
+ remaining -= status;
+ buffer = ((char *)buffer) + status;
}
+
+ mStandby = false;
return bytes;
+
+Error:
+ // Simulate audio output timing in case of error
+ usleep(bytes * 1000000 / frameSize() / sampleRate());
+
+ return status;
}
status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
{
- return 0;
+ int result = 0;
+
+ if (!mStandby) {
+ result = a2dp_stop(mData);
+ if (result == 0)
+ mStandby = true;
+ }
+
+ return result;
}
status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 03bf933..b8119a1 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -35,7 +35,6 @@ public:
A2dpAudioInterface();
virtual ~A2dpAudioInterface();
virtual status_t initCheck();
- virtual status_t standby();
virtual status_t setVoiceVolume(float volume);
virtual status_t setMasterVolume(float volume);
@@ -74,11 +73,11 @@ private:
int channelCount,
uint32_t sampleRate);
virtual uint32_t sampleRate() const { return 44100; }
- // must be 32-bit aligned - driver only seems to like 4800
- virtual size_t bufferSize() const { return 5120; }
+ // SBC codec wants a multiple of 512
+ virtual size_t bufferSize() const { return 512 * 30; }
virtual int channelCount() const { return 2; }
virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return 0; }
+ virtual uint32_t latency() const { return ((1000*channelCount()*bufferSize())/frameSize())/sampleRate() + 200; }
virtual status_t setVolume(float volume) { return INVALID_OPERATION; }
virtual ssize_t write(const void* buffer, size_t bytes);
status_t standby();
@@ -86,14 +85,11 @@ private:
private:
int mFd;
+ bool mStandby;
int mStartCount;
int mRetryCount;
void* mData;
bool mInitialized;
-
-#define kBufferSize 50000
- char mBuffer[kBufferSize];
- int mBufferRemaining;
};
Mutex mLock;
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
index 8eee9cc..b4940cb 100644
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -49,14 +49,6 @@ AudioDumpInterface::~AudioDumpInterface()
}
-status_t AudioDumpInterface::standby()
-{
- if(mStreamOut) mStreamOut->Close();
- gFirst = true;
- return mFinalInterface->standby();
-}
-
-
AudioStreamOut* AudioDumpInterface::openOutputStream(
int format, int channelCount, uint32_t sampleRate, status_t *status)
{
@@ -106,6 +98,14 @@ ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
return ret;
}
+status_t AudioStreamOutDump::standby()
+{
+ Close();
+ gFirst = true;
+ return mFinalStream->standby();
+}
+
+
void AudioStreamOutDump::Close(void)
{
if(mOutFile) {
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index a65e56a..82b5250 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -40,6 +40,7 @@ public:
virtual uint32_t latency() const { return mFinalStream->latency(); }
virtual status_t setVolume(float volume)
{ return mFinalStream->setVolume(volume); }
+ virtual status_t standby();
virtual status_t dump(int fd, const Vector<String16>& args) { return mFinalStream->dump(fd, args); }
void Close(void);
@@ -54,7 +55,6 @@ class AudioDumpInterface : public AudioHardwareBase
public:
AudioDumpInterface(AudioHardwareInterface* hw);
- virtual status_t standby();
virtual AudioStreamOut* openOutputStream(
int format=0,
int channelCount=0,
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 53b18ad..d4692ad 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -100,11 +100,11 @@ static bool settingsAllowed() {
AudioFlinger::AudioFlinger()
: BnAudioFlinger(), Thread(false),
mMasterVolume(0), mMasterMute(true), mHardwareAudioMixer(0), mA2dpAudioMixer(0),
- mAudioMixer(0), mAudioHardware(0), mA2dpAudioInterface(0),
- mHardwareOutput(0), mA2dpOutput(0), mOutput(0), mAudioRecordThread(0),
- mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0),
- mMixBuffer(0), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0),
- mStandby(false), mInWrite(false)
+ mAudioMixer(0), mAudioHardware(0), mA2dpAudioInterface(0), mHardwareOutput(0),
+ mA2dpOutput(0), mOutput(0), mRequestedOutput(0), mAudioRecordThread(0),
+ mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
+ mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
+ mInWrite(false)
{
mHardwareStatus = AUDIO_HW_IDLE;
mAudioHardware = AudioHardwareInterface::create();
@@ -116,9 +116,9 @@ AudioFlinger::AudioFlinger()
mHardwareOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
mHardwareStatus = AUDIO_HW_IDLE;
if (mHardwareOutput) {
- mSampleRate = mHardwareOutput->sampleRate();
- mHardwareAudioMixer = new AudioMixer(getOutputFrameCount(mHardwareOutput), mSampleRate);
- setOutput(mHardwareOutput);
+ mHardwareAudioMixer = new AudioMixer(getOutputFrameCount(mHardwareOutput), mHardwareOutput->sampleRate());
+ mRequestedOutput = mHardwareOutput;
+ doSetOutput(mHardwareOutput);
// FIXME - this should come from settings
setMasterVolume(1.0f);
@@ -159,7 +159,6 @@ AudioFlinger::AudioFlinger()
}
char value[PROPERTY_VALUE_MAX];
- // FIXME: What property should this be???
property_get("ro.audio.silent", value, "0");
if (atoi(value)) {
LOGD("Silence is golden");
@@ -173,9 +172,8 @@ AudioFlinger::~AudioFlinger()
mAudioRecordThread->exit();
mAudioRecordThread.clear();
}
- delete mOutput;
- delete mA2dpOutput;
delete mAudioHardware;
+ // deleting mA2dpAudioInterface also deletes mA2dpOutput;
delete mA2dpAudioInterface;
delete [] mMixBuffer;
delete mHardwareAudioMixer;
@@ -184,26 +182,22 @@ AudioFlinger::~AudioFlinger()
void AudioFlinger::setOutput(AudioStreamOut* output)
{
- // lock on mOutputLock to prevent threadLoop() from starving us
- Mutex::Autolock _l2(mOutputLock);
-
- // to synchronize with threadLoop()
- Mutex::Autolock _l(mLock);
+ mRequestedOutput = output;
+}
- if (mOutput != output) {
- mSampleRate = output->sampleRate();
- mChannelCount = output->channelCount();
-
- // FIXME - Current mixer implementation only supports stereo output
- if (mChannelCount == 1) {
- LOGE("Invalid audio hardware channel count");
- }
- mFormat = output->format();
- mFrameCount = getOutputFrameCount(output);
-
- mAudioMixer = (output == mA2dpOutput ? mA2dpAudioMixer : mHardwareAudioMixer);
- mOutput = output;
+void AudioFlinger::doSetOutput(AudioStreamOut* output)
+{
+ mSampleRate = output->sampleRate();
+ mChannelCount = output->channelCount();
+
+ // FIXME - Current mixer implementation only supports stereo output
+ if (mChannelCount == 1) {
+ LOGE("Invalid audio hardware channel count");
}
+ mFormat = output->format();
+ mFrameCount = getOutputFrameCount(output);
+ mAudioMixer = (output == mA2dpOutput ? mA2dpAudioMixer : mHardwareAudioMixer);
+ mOutput = output;
}
size_t AudioFlinger::getOutputFrameCount(AudioStreamOut* output)
@@ -330,21 +324,11 @@ bool AudioFlinger::threadLoop()
Vector< sp<Track> > tracksToRemove;
size_t enabledTracks = 0;
nsecs_t standbyTime = systemTime();
- AudioMixer* mixer = 0;
- size_t frameCount = 0;
- int channelCount = 0;
- uint32_t sampleRate = 0;
- AudioStreamOut* output = 0;
do {
enabledTracks = 0;
{ // scope for the mLock
- // locking briefly on the secondary mOutputLock is necessary to avoid
- // having this thread starve the thread that called setOutput()
- mOutputLock.lock();
- mOutputLock.unlock();
-
Mutex::Autolock _l(mLock);
const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
@@ -354,7 +338,7 @@ bool AudioFlinger::threadLoop()
LOGV("Audio hardware entering standby\n");
mHardwareStatus = AUDIO_HW_STANDBY;
if (!mStandby) {
- mAudioHardware->standby();
+ mOutput->standby();
mStandby = true;
}
mHardwareStatus = AUDIO_HW_IDLE;
@@ -366,15 +350,16 @@ bool AudioFlinger::threadLoop()
continue;
}
- // get active mixer and output parameter while the lock is held and keep them
- // consistent till the next loop.
-
- mixer = audioMixer();
- frameCount = mFrameCount;
- channelCount = mChannelCount;
- sampleRate = mSampleRate;
- output = mOutput;
-
+ // check for change in output
+ if (mRequestedOutput != mOutput) {
+
+ // put current output into standby mode
+ if (mOutput) mOutput->standby();
+
+ // change output
+ doSetOutput(mRequestedOutput);
+ }
+
// find out which tracks need to be processed
size_t count = activeTracks.size();
for (size_t i=0 ; i<count ; i++) {
@@ -386,7 +371,7 @@ bool AudioFlinger::threadLoop()
// The first time a track is added we wait
// for all its buffers to be filled before processing it
- mixer->setActiveTrack(track->name());
+ mAudioMixer->setActiveTrack(track->name());
if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
!track->isPaused())
{
@@ -412,8 +397,8 @@ bool AudioFlinger::threadLoop()
}
// XXX: these things DON'T need to be done each time
- mixer->setBufferProvider(track);
- mixer->enable(AudioMixer::MIXING);
+ mAudioMixer->setBufferProvider(track);
+ mAudioMixer->enable(AudioMixer::MIXING);
int param;
if ( track->mFillingUpStatus == Track::FS_FILLED) {
@@ -428,15 +413,15 @@ bool AudioFlinger::threadLoop()
} else {
param = AudioMixer::RAMP_VOLUME;
}
- mixer->setParameter(param, AudioMixer::VOLUME0, left);
- mixer->setParameter(param, AudioMixer::VOLUME1, right);
- mixer->setParameter(
+ mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
+ mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
+ mAudioMixer->setParameter(
AudioMixer::TRACK,
AudioMixer::FORMAT, track->format());
- mixer->setParameter(
+ mAudioMixer->setParameter(
AudioMixer::TRACK,
AudioMixer::CHANNEL_COUNT, track->channelCount());
- mixer->setParameter(
+ mAudioMixer->setParameter(
AudioMixer::RESAMPLE,
AudioMixer::SAMPLE_RATE,
int(cblk->sampleRate));
@@ -463,7 +448,7 @@ bool AudioFlinger::threadLoop()
}
}
// LOGV("disable(%d)", track->name());
- mixer->disable(AudioMixer::MIXING);
+ mAudioMixer->disable(AudioMixer::MIXING);
}
}
@@ -475,27 +460,27 @@ bool AudioFlinger::threadLoop()
mActiveTracks.remove(track);
if (track->isTerminated()) {
mTracks.remove(track);
- mixer->deleteTrackName(track->mName);
+ mAudioMixer->deleteTrackName(track->mName);
}
}
}
}
if (LIKELY(enabledTracks)) {
// mix buffers...
- mixer->process(curBuf);
+ mAudioMixer->process(curBuf);
// output audio to hardware
mLastWriteTime = systemTime();
mInWrite = true;
- size_t mixBufferSize = frameCount*channelCount*sizeof(int16_t);
- output->write(curBuf, mixBufferSize);
+ size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
+ mOutput->write(curBuf, mixBufferSize);
mNumWrites++;
mInWrite = false;
mStandby = false;
nsecs_t temp = systemTime();
standbyTime = temp + kStandbyTimeInNsecs;
nsecs_t delta = temp - mLastWriteTime;
- nsecs_t maxPeriod = seconds(frameCount) / sampleRate * 2;
+ nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
if (delta > maxPeriod) {
LOGW("write blocked for %llu msecs", ns2ms(delta));
mNumDelayedWrites++;
@@ -653,6 +638,8 @@ status_t AudioFlinger::setMasterVolume(float value)
status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
{
+ status_t err = NO_ERROR;
+
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
@@ -677,16 +664,20 @@ status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
}
#endif
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_GET_ROUTING;
- uint32_t r;
- uint32_t err = mAudioHardware->getRouting(mode, &r);
- if (err == NO_ERROR) {
- r = (r & ~mask) | (routes & mask);
- mHardwareStatus = AUDIO_HW_SET_ROUTING;
- err = mAudioHardware->setRouting(mode, r);
+ // do nothing if only A2DP routing is affected
+ mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
+ if (mask) {
+ AutoMutex lock(mHardwareLock);
+ mHardwareStatus = AUDIO_HW_GET_ROUTING;
+ uint32_t r;
+ err = mAudioHardware->getRouting(mode, &r);
+ if (err == NO_ERROR) {
+ r = (r & ~mask) | (routes & mask);
+ mHardwareStatus = AUDIO_HW_SET_ROUTING;
+ err = mAudioHardware->setRouting(mode, r);
+ }
+ mHardwareStatus = AUDIO_HW_IDLE;
}
- mHardwareStatus = AUDIO_HW_IDLE;
return err;
}
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index d9f7b49..7c84e62 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -150,6 +150,7 @@ private:
virtual ~AudioFlinger();
void setOutput(AudioStreamOut* output);
+ void doSetOutput(AudioStreamOut* output);
size_t getOutputFrameCount(AudioStreamOut* output);
// Internal dump utilites.
@@ -450,7 +451,6 @@ private:
mutable Mutex mHardwareLock;
mutable Mutex mLock;
- mutable Mutex mOutputLock;
mutable Condition mWaitWorkCV;
DefaultKeyedVector< pid_t, wp<Client> > mClients;
SortedVector< wp<Track> > mActiveTracks;
@@ -468,6 +468,7 @@ private:
AudioStreamOut* mHardwareOutput;
AudioStreamOut* mA2dpOutput;
AudioStreamOut* mOutput;
+ AudioStreamOut* mRequestedOutput;
sp<AudioRecordThread> mAudioRecordThread;
uint32_t mSampleRate;
size_t mFrameCount;
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
index e6a163b..e455186 100644
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -61,12 +61,6 @@ status_t AudioHardwareGeneric::initCheck()
return NO_INIT;
}
-status_t AudioHardwareGeneric::standby()
-{
- // Implement: audio hardware to standby mode
- return NO_ERROR;
-}
-
AudioStreamOut* AudioHardwareGeneric::openOutputStream(
int format, int channelCount, uint32_t sampleRate, status_t *status)
{
@@ -215,6 +209,12 @@ ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
return ssize_t(::write(mFd, buffer, bytes));
}
+status_t AudioStreamOutGeneric::standby()
+{
+ // Implement: audio hardware to standby mode
+ return NO_ERROR;
+}
+
status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
index a2342cd..bc006b8 100644
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -50,6 +50,7 @@ public:
virtual uint32_t latency() const { return 0; }
virtual status_t setVolume(float volume) { return INVALID_OPERATION; }
virtual ssize_t write(const void* buffer, size_t bytes);
+ virtual status_t standby();
virtual status_t dump(int fd, const Vector<String16>& args);
private:
@@ -92,7 +93,6 @@ public:
AudioHardwareGeneric();
virtual ~AudioHardwareGeneric();
virtual status_t initCheck();
- virtual status_t standby();
virtual status_t setVoiceVolume(float volume);
virtual status_t setMasterVolume(float volume);
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index d309902..e9f3d69 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -41,11 +41,6 @@ status_t AudioHardwareStub::initCheck()
return NO_ERROR;
}
-status_t AudioHardwareStub::standby()
-{
- return NO_ERROR;
-}
-
AudioStreamOut* AudioHardwareStub::openOutputStream(
int format, int channelCount, uint32_t sampleRate, status_t *status)
{
@@ -125,6 +120,11 @@ ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
return bytes;
}
+status_t AudioStreamOutStub::standby()
+{
+ return NO_ERROR;
+}
+
status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
index 5316d60..7ec5b95 100644
--- a/libs/audioflinger/AudioHardwareStub.h
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -37,6 +37,7 @@ public:
virtual uint32_t latency() const { return 0; }
virtual status_t setVolume(float volume) { return NO_ERROR; }
virtual ssize_t write(const void* buffer, size_t bytes);
+ virtual status_t standby();
virtual status_t dump(int fd, const Vector<String16>& args);
};
@@ -59,7 +60,6 @@ public:
AudioHardwareStub();
virtual ~AudioHardwareStub();
virtual status_t initCheck();
- virtual status_t standby();
virtual status_t setVoiceVolume(float volume);
virtual status_t setMasterVolume(float volume);
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
index e9e34c3..d18f59a 100644
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ b/libs/surfaceflinger/BootAnimation.cpp
@@ -36,8 +36,8 @@
#include <ui/ISurfaceFlingerClient.h>
#include <ui/EGLNativeWindowSurface.h>
-#include <graphics/SkBitmap.h>
-#include <graphics/SkImageDecoder.h>
+#include <core/SkBitmap.h>
+#include <images/SkImageDecoder.h>
#include <GLES/egl.h>
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index cd72179..19e32ec 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -250,7 +250,7 @@ void DisplayHardware::init(uint32_t dpy)
mOverlayEngine = NULL;
if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
- overlay_open(module, &mOverlayEngine);
+ overlay_control_open(module, &mOverlayEngine);
}
}
@@ -266,7 +266,7 @@ void DisplayHardware::fini()
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglTerminate(mDisplay);
copybit_close(mBlitEngine);
- overlay_close(mOverlayEngine);
+ overlay_control_close(mOverlayEngine);
}
void DisplayHardware::releaseScreen() const
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index de4a2cc..df97b60 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -26,7 +26,7 @@
#include "DisplayHardware/DisplayHardwareBase.h"
-struct overlay_device_t;
+struct overlay_control_device_t;
struct copybit_device_t;
struct copybit_image_t;
struct copybit_t;
@@ -78,7 +78,7 @@ public:
void getDisplaySurface(GGLSurface* fb) const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
copybit_device_t* getBlitEngine() const { return mBlitEngine; }
- overlay_device_t* getOverlayEngine() const { return mOverlayEngine; }
+ overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
Rect bounds() const {
return Rect(mWidth, mHeight);
@@ -103,7 +103,7 @@ private:
mutable Region mDirty;
sp<EGLDisplaySurface> mDisplaySurface;
copybit_device_t* mBlitEngine;
- overlay_device_t* mOverlayEngine;
+ overlay_control_device_t* mOverlayEngine;
};
}; // namespace android
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 8ba0851..f65d669 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -316,7 +316,7 @@ uint32_t Layer::doTransaction(uint32_t flags)
if (err == NO_ERROR) {
const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
android_atomic_and(~mask, &(lcblk->swapState));
- // since a buffer became availlable, we can let the client go...
+ // since a buffer became available, we can let the client go...
mFlinger->scheduleBroadcast(client);
mResizeTransactionDone = true;
@@ -511,7 +511,7 @@ Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions)
}
mResizeTransactionDone = false;
recomputeVisibleRegions = true;
- invalidate = true;
+ this->contentDirty = true;
}
}
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index af353e2..bdefba3 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -53,14 +53,15 @@ Vector<GLuint> LayerBase::deletedTextures;
int32_t LayerBase::sIdentity = 0;
LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
- : dpy(display), invalidate(false),
+ : dpy(display), contentDirty(false),
mFlinger(flinger),
mTransformed(false),
mOrientation(0),
mCanUseCopyBit(false),
mTransactionFlags(0),
mPremultipliedAlpha(true),
- mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
+ mIdentity(uint32_t(android_atomic_inc(&sIdentity))),
+ mInvalidate(0)
{
const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
mFlags = hw.getFlags();
@@ -205,7 +206,7 @@ uint32_t LayerBase::doTransaction(uint32_t flags)
if (temp.sequence != front.sequence) {
// invalidate and recompute the visible regions if needed
flags |= eVisibleRegion;
- this->invalidate = true;
+ this->contentDirty = true;
}
// Commit the transaction
@@ -299,12 +300,22 @@ void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
void LayerBase::unlockPageFlip(
const Transform& planeTransform, Region& outDirtyRegion)
{
+ if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
+ outDirtyRegion.orSelf(visibleRegionScreen);
+ }
}
void LayerBase::finishPageFlip()
{
}
+void LayerBase::invalidate()
+{
+ if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
+ mFlinger->signalEvent();
+ }
+}
+
void LayerBase::drawRegion(const Region& reg) const
{
Region::iterator iterator(reg);
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index b3f3771..5e14dc8 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -75,7 +75,7 @@ public:
virtual ~LayerBase();
DisplayID dpy;
- mutable bool invalidate;
+ mutable bool contentDirty;
Region visibleRegionScreen;
Region transparentRegionScreen;
Region coveredRegionScreen;
@@ -112,18 +112,87 @@ public:
Rect visibleBounds() const;
void drawRegion(const Region& reg) const;
+ void invalidate();
+
+ /**
+ * draw - performs some global clipping optimizations
+ * and calls onDraw().
+ * Typically this method is not overridden, instead implement onDraw()
+ * to perform the actual drawing.
+ */
virtual void draw(const Region& clip) const;
+
+ /**
+ * onDraw - draws the surface.
+ */
virtual void onDraw(const Region& clip) const = 0;
+
+ /**
+ * initStates - called just after construction
+ */
virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+
+ /**
+ * setSizeChanged - called when the *current* state's size is changed.
+ */
virtual void setSizeChanged(uint32_t w, uint32_t h);
+
+ /**
+ * doTransaction - process the transaction. This is a good place to figure
+ * out which attributes of the surface have changed.
+ */
virtual uint32_t doTransaction(uint32_t transactionFlags);
+
+ /**
+ * setVisibleRegion - called to set the new visible region. This gives
+ * a chance to update the new visible region or record the fact it changed.
+ */
virtual void setVisibleRegion(const Region& visibleRegion);
+
+ /**
+ * setCoveredRegion - called when the covered region changes. The covered
+ * region correspond to any area of the surface that is covered
+ * (transparently or not) by another surface.
+ */
virtual void setCoveredRegion(const Region& coveredRegion);
+
+ /**
+ * getPhysicalSize - returns the physical size of the drawing state of
+ * the surface. If the surface is backed by a bitmap, this is the size of
+ * the bitmap (as opposed to the size of the drawing state).
+ */
virtual Point getPhysicalSize() const;
+
+ /**
+ * lockPageFlip - called each time the screen is redrawn and returns whether
+ * the visible regions need to be recomputed (this is a fairly heavy
+ * operation, so this should be set only if needed). Typically this is used
+ * to figure out if the content or size of a surface has changed.
+ */
virtual void lockPageFlip(bool& recomputeVisibleRegions);
+
+ /**
+ * unlockPageFlip - called each time the screen is redrawn. updates the
+ * final dirty region wrt the planeTransform.
+ * At this point, all visible regions, surface position and size, etc... are
+ * correct.
+ */
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+
+ /**
+ * finishPageFlip - called after all surfaces have drawn.
+ */
virtual void finishPageFlip();
+
+ /**
+ * needsBlending - true if this surface needs blending
+ */
virtual bool needsBlending() const { return false; }
+
+ /**
+ * isSecure - true if this surface is secure, that is if it prevents a
+ * screenshot to be taken,
+ */
virtual bool isSecure() const { return false; }
enum { // flags for doTransaction()
@@ -162,7 +231,6 @@ protected:
bool canUseCopybit() const;
-
SurfaceFlinger* mFlinger;
uint32_t mFlags;
@@ -184,7 +252,10 @@ protected:
bool mPremultipliedAlpha;
// only read
- const uint32_t mIdentity;
+ const uint32_t mIdentity;
+
+ // atomic
+ volatile int32_t mInvalidate;
private:
@@ -254,7 +325,7 @@ public:
{ return INVALID_OPERATION; }
virtual void postBuffer(ssize_t offset) { }
virtual void unregisterBuffers() { };
- virtual sp<Overlay> createOverlay(
+ virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format) {
return NULL;
};
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index e3ae7fb..efadbcf 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -71,7 +71,7 @@ uint32_t LayerBlur::doTransaction(uint32_t flags)
mRefreshCache = true;
mCacheDirty = true;
flags |= eVisibleRegion;
- this->invalidate = true;
+ this->contentDirty = true;
}
return LayerBase::doTransaction(flags);
}
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 3861e68..700e4f5 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -46,7 +46,7 @@ const char* const LayerBuffer::typeID = "LayerBuffer";
LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
Client* client, int32_t i)
: LayerBaseClient(flinger, display, client, i),
- mBuffer(0), mTextureName(-1U), mInvalidate(false), mNeedsBlending(false)
+ mNeedsBlending(false)
{
}
@@ -57,43 +57,333 @@ LayerBuffer::~LayerBuffer()
s->disown();
mClientSurface.clear();
}
+}
- // this should always be called from the OpenGL thread
- if (mTextureName != -1U) {
- //glDeleteTextures(1, &mTextureName);
- deletedTextures.add(mTextureName);
- }
- // to help debugging we set those to zero
- mWidth = mHeight = 0;
+sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
+{
+ Mutex::Autolock _l(mLock);
+ return mClientSurface.promote();
}
-bool LayerBuffer::needsBlending() const
+sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
{
+ sp<SurfaceBuffer> s;
Mutex::Autolock _l(mLock);
+ s = mClientSurface.promote();
+ if (s == 0) {
+ s = new SurfaceBuffer(clientIndex(),
+ const_cast<LayerBuffer *>(this));
+ mClientSurface = s;
+ }
+ return s;
+}
+
+bool LayerBuffer::needsBlending() const {
return mNeedsBlending;
}
+void LayerBuffer::setNeedsBlending(bool blending) {
+ mNeedsBlending = blending;
+}
+
+void LayerBuffer::postBuffer(ssize_t offset)
+{
+ sp<Source> source(getSource());
+ if (source != 0)
+ source->postBuffer(offset);
+}
+
+void LayerBuffer::unregisterBuffers()
+{
+ sp<Source> source(getSource());
+ if (source != 0)
+ source->unregisterBuffers();
+ // XXX: clear mSource
+}
+
+uint32_t LayerBuffer::doTransaction(uint32_t flags)
+{
+ sp<Source> source(getSource());
+ if (source != 0)
+ source->onTransaction(flags);
+ return LayerBase::doTransaction(flags);
+}
+
+void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
+ Region& outDirtyRegion)
+{
+ // this code-path must be as tight as possible, it's called each time
+ // the screen is composited.
+ sp<Source> source(getSource());
+ if (source != 0)
+ source->onVisibilityResolved(planeTransform);
+ LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
+}
+
void LayerBuffer::onDraw(const Region& clip) const
{
+ sp<Source> source(getSource());
+ if (LIKELY(source != 0)) {
+ source->onDraw(clip);
+ } else {
+ clearWithOpenGL(clip);
+ }
+}
+
+/**
+ * This creates a "buffer" source for this surface
+ */
+status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride,
+ PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
+{
+ Mutex::Autolock _l(mLock);
+ if (mSource != 0)
+ return INVALID_OPERATION;
+
+ sp<BufferSource> source = new BufferSource(*this, w, h,
+ hstride, vstride, format, memoryHeap);
+
+ status_t result = source->getStatus();
+ if (result == NO_ERROR) {
+ mSource = source;
+ }
+ return result;
+}
+
+/**
+ * This creates an "overlay" source for this surface
+ */
+sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
+{
+ sp<OverlayRef> result;
+ Mutex::Autolock _l(mLock);
+ if (mSource != 0)
+ return result;
+
+ sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f);
+ if (result != 0) {
+ mSource = source;
+ }
+ return result;
+}
+
+sp<LayerBuffer::Source> LayerBuffer::getSource() const {
+ Mutex::Autolock _l(mLock);
+ return mSource;
+}
+
+// ============================================================================
+// LayerBuffer::SurfaceBuffer
+// ============================================================================
+
+LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
+: LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
+{
+}
+
+LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
+{
+ unregisterBuffers();
+ mOwner = 0;
+}
+
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(
+ int w, int h, int hs, int vs,
+ PixelFormat format, const sp<IMemoryHeap>& heap)
+{
+ LayerBuffer* owner(getOwner());
+ if (owner)
+ return owner->registerBuffers(w, h, hs, vs, format, heap);
+ return NO_INIT;
+}
+
+void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
+{
+ LayerBuffer* owner(getOwner());
+ if (owner)
+ owner->postBuffer(offset);
+}
+
+void LayerBuffer::SurfaceBuffer::unregisterBuffers()
+{
+ LayerBuffer* owner(getOwner());
+ if (owner)
+ owner->unregisterBuffers();
+}
+
+sp<OverlayRef> LayerBuffer::SurfaceBuffer::createOverlay(
+ uint32_t w, uint32_t h, int32_t format) {
+ sp<OverlayRef> result;
+ LayerBuffer* owner(getOwner());
+ if (owner)
+ result = owner->createOverlay(w, h, format);
+ return result;
+}
+
+void LayerBuffer::SurfaceBuffer::disown()
+{
+ Mutex::Autolock _l(mLock);
+ mOwner = 0;
+}
+
+// ============================================================================
+// LayerBuffer::Buffer
+// ============================================================================
+
+LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
+ int w, int h, int hs, int vs, int f)
+: mHeap(heap)
+{
+ NativeBuffer& src(mNativeBuffer);
+ src.crop.l = 0;
+ src.crop.t = 0;
+ src.crop.r = w;
+ src.crop.b = h;
+ src.img.w = hs ?: w;
+ src.img.h = vs ?: h;
+ src.img.format = f;
+ src.img.offset = offset;
+ src.img.base = heap->base();
+ src.img.fd = heap->heapID();
+ // FIXME: make sure this buffer lies within the heap, in which case, set
+ // mHeap to null
+}
+
+LayerBuffer::Buffer::~Buffer()
+{
+}
+
+// ============================================================================
+// LayerBuffer::Source
+// LayerBuffer::BufferSource
+// LayerBuffer::OverlaySource
+// ============================================================================
+
+LayerBuffer::Source::Source(LayerBuffer& layer)
+ : mLayer(layer)
+{
+}
+LayerBuffer::Source::~Source() {
+}
+void LayerBuffer::Source::onDraw(const Region& clip) const {
+}
+void LayerBuffer::Source::onTransaction(uint32_t flags) {
+}
+void LayerBuffer::Source::onVisibilityResolved(
+ const Transform& planeTransform) {
+}
+void LayerBuffer::Source::postBuffer(ssize_t offset) {
+}
+void LayerBuffer::Source::unregisterBuffers() {
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
+ int w, int h, int hstride, int vstride,
+ PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
+ : Source(layer), mStatus(NO_ERROR), mTextureName(-1U)
+{
+ if (memoryHeap == NULL) {
+ // this is allowed, but in this case, it is illegal to receive
+ // postBuffer(). The surface just erases the framebuffer with
+ // fully transparent pixels.
+ mHeap.clear();
+ mWidth = w;
+ mHeight = h;
+ mLayer.setNeedsBlending(false);
+ return;
+ }
+
+ status_t err = (memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT;
+ if (err != NO_ERROR) {
+ mStatus = err;
+ return;
+ }
+
+ // TODO: validate format/parameters
+ mHeap = memoryHeap;
+ mWidth = w;
+ mHeight = h;
+ mHStride = hstride;
+ mVStride = vstride;
+ mFormat = format;
+ PixelFormatInfo info;
+ getPixelFormatInfo(format, &info);
+ mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);
+}
+
+LayerBuffer::BufferSource::~BufferSource()
+{
+ if (mTextureName != -1U) {
+ LayerBase::deletedTextures.add(mTextureName);
+ }
+}
+
+void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
+{
+ sp<IMemoryHeap> heap;
+ int w, h, hs, vs, f;
+ { // scope for the lock
+ Mutex::Autolock _l(mLock);
+ w = mWidth;
+ h = mHeight;
+ hs= mHStride;
+ vs= mVStride;
+ f = mFormat;
+ heap = mHeap;
+ }
+
+ sp<Buffer> buffer;
+ if (heap != 0) {
+ buffer = new LayerBuffer::Buffer(heap, offset, w, h, hs, vs, f);
+ if (buffer->getStatus() != NO_ERROR)
+ buffer.clear();
+ setBuffer(buffer);
+ mLayer.invalidate();
+ }
+}
+
+void LayerBuffer::BufferSource::unregisterBuffers()
+{
+ Mutex::Autolock _l(mLock);
+ mHeap.clear();
+ mBuffer.clear();
+ mLayer.invalidate();
+}
+
+sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
+{
+ Mutex::Autolock _l(mLock);
+ return mBuffer;
+}
+
+void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
+{
+ Mutex::Autolock _l(mLock);
+ mBuffer = buffer;
+}
+
+void LayerBuffer::BufferSource::onDraw(const Region& clip) const
+{
sp<Buffer> buffer(getBuffer());
if (UNLIKELY(buffer == 0)) {
// nothing to do, we don't have a buffer
- clearWithOpenGL(clip);
+ mLayer.clearWithOpenGL(clip);
return;
}
status_t err = NO_ERROR;
NativeBuffer src(buffer->getBuffer());
- const int can_use_copybit = canUseCopybit();
+ const Rect& transformedBounds = mLayer.getTransformedBounds();
+ const int can_use_copybit = mLayer.canUseCopybit();
if (can_use_copybit) {
- //StopWatch watch("MDP");
-
const int src_width = src.crop.r - src.crop.l;
const int src_height = src.crop.b - src.crop.t;
- int W = mTransformedBounds.width();
- int H = mTransformedBounds.height();
- if (getOrientation() & Transform::ROT_90) {
+ int W = transformedBounds.width();
+ int H = transformedBounds.height();
+ if (mLayer.getOrientation() & Transform::ROT_90) {
int t(W); W=H; H=t;
}
@@ -104,7 +394,7 @@ void LayerBuffer::onDraw(const Region& clip) const
* the requested scale factor, in which case we perform the scaling
* in several passes. */
- copybit_device_t* copybit = mFlinger->getBlitEngine();
+ copybit_device_t* copybit = mLayer.mFlinger->getBlitEngine();
const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
@@ -117,13 +407,10 @@ void LayerBuffer::onDraw(const Region& clip) const
else if (src_height*mag < H) yscale = mag;
if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
- //LOGD("MDP scaling hack w=%d, h=%d, ww=%d, wh=%d, xs=%f, ys=%f",
- // src_width, src_height, W, H, xscale, yscale);
-
if (UNLIKELY(mTemporaryDealer == 0)) {
// allocate a memory-dealer for this the first time
- mTemporaryDealer = mFlinger->getSurfaceHeapManager()
- ->createHeap(ISurfaceComposer::eHardware);
+ mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager()
+ ->createHeap(ISurfaceComposer::eHardware);
mTempBitmap.init(mTemporaryDealer);
}
@@ -149,14 +436,14 @@ void LayerBuffer::onDraw(const Region& clip) const
}
}
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware());
copybit_image_t dst;
hw.getDisplaySurface(&dst);
const copybit_rect_t& drect
- = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
- const State& s(drawingState());
+ = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
+ const State& s(mLayer.drawingState());
region_iterator it(clip);
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
+ copybit->set_parameter(copybit, COPYBIT_TRANSFORM, mLayer.getOrientation());
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
copybit->set_parameter(copybit, COPYBIT_DITHER,
s.flags & ISurfaceComposer::eLayerDither ?
@@ -167,245 +454,115 @@ void LayerBuffer::onDraw(const Region& clip) const
if (!can_use_copybit || err) {
if (UNLIKELY(mTextureName == -1LU)) {
- mTextureName = createTexture();
+ mTextureName = mLayer.createTexture();
}
GLuint w = 0;
GLuint h = 0;
GGLSurface t;
- t.version = sizeof(GGLSurface);
- t.width = src.crop.r;
- t.height = src.crop.b;
- t.stride = src.img.w;
- t.vstride= src.img.h;
- t.format = src.img.format;
- t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
+ t.version = sizeof(GGLSurface);
+ t.width = src.crop.r;
+ t.height = src.crop.b;
+ t.stride = src.img.w;
+ t.vstride= src.img.h;
+ t.format = src.img.format;
+ t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
const Region dirty(Rect(t.width, t.height));
- loadTexture(dirty, mTextureName, t, w, h);
- drawWithOpenGL(clip, mTextureName, t);
+ mLayer.loadTexture(dirty, mTextureName, t, w, h);
+ mLayer.drawWithOpenGL(clip, mTextureName, t);
}
}
-void LayerBuffer::invalidateLocked()
-{
- mInvalidate = true;
- mFlinger->signalEvent();
-}
-
-void LayerBuffer::invalidate()
-{
- Mutex::Autolock _l(mLock);
- invalidateLocked();
-}
-
-void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
- Region& outDirtyRegion)
-{
- Mutex::Autolock _l(mLock);
- if (mInvalidate) {
- mInvalidate = false;
- outDirtyRegion.orSelf(visibleRegionScreen);
- }
-}
-
-sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
-{
- Mutex::Autolock _l(mLock);
- return mClientSurface.promote();
-}
-
-sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
-{
- sp<SurfaceBuffer> s;
- Mutex::Autolock _l(mLock);
- s = mClientSurface.promote();
- if (s == 0) {
- s = new SurfaceBuffer(clientIndex(),
- const_cast<LayerBuffer *>(this));
- mClientSurface = s;
- }
- return s;
-}
-
-
-status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride,
- PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
-{
- if (memoryHeap == NULL) {
- // this is allowed, but in this case, it is illegal to receive
- // postBuffer(). The surface just erases the framebuffer with
- // fully transparent pixels.
- mHeap.clear();
- mWidth = w;
- mHeight = h;
- mNeedsBlending = false;
- return NO_ERROR;
- }
-
- status_t err = (memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT;
- if (err != NO_ERROR)
- return err;
-
- // TODO: validate format/parameters
-
- Mutex::Autolock _l(mLock);
- mHeap = memoryHeap;
- mWidth = w;
- mHeight = h;
- mHStride = hstride;
- mVStride = vstride;
- mFormat = format;
- PixelFormatInfo info;
- getPixelFormatInfo(format, &info);
- mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
- return NO_ERROR;
-}
-
-void LayerBuffer::postBuffer(ssize_t offset)
-{
- sp<IMemoryHeap> heap;
- int w, h, hs, vs, f;
- { // scope for the lock
- Mutex::Autolock _l(mLock);
- w = mWidth;
- h = mHeight;
- hs= mHStride;
- vs= mVStride;
- f = mFormat;
- heap = mHeap;
- }
-
- sp<Buffer> buffer;
- if (heap != 0) {
- buffer = new Buffer(heap, offset, w, h, hs, vs, f);
- if (buffer->getStatus() != NO_ERROR)
- buffer.clear();
- setBuffer(buffer);
- invalidate();
- }
-}
+// ---------------------------------------------------------------------------
-void LayerBuffer::unregisterBuffers()
+LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
+ sp<OverlayRef>* overlayRef,
+ uint32_t w, uint32_t h, int32_t format)
+ : Source(layer), mVisibilityChanged(false), mOverlay(0), mOverlayHandle(0)
{
- Mutex::Autolock _l(mLock);
- mHeap.clear();
- mBuffer.clear();
- invalidateLocked();
-}
+ overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();
-sp<Overlay> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t format)
-{
- sp<Overlay> result;
- Mutex::Autolock _l(mLock);
- if (mHeap != 0 || mBuffer != 0) {
- // we're a push surface. error.
- return result;
- }
-
- overlay_device_t* overlay_dev = mFlinger->getOverlayEngine();
if (overlay_dev == NULL) {
// overlays not supported
- return result;
+ return;
}
overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
if (overlay == NULL) {
// couldn't create the overlay (no memory? no more overlays?)
- return result;
+ return;
}
-
- /* TODO: implement the real stuff here */
-
- return result;
-}
-
-sp<LayerBuffer::Buffer> LayerBuffer::getBuffer() const
-{
- Mutex::Autolock _l(mLock);
- return mBuffer;
-}
-void LayerBuffer::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
-{
- Mutex::Autolock _l(mLock);
- mBuffer = buffer;
-}
+ // enable dithering...
+ overlay_dev->setParameter(overlay_dev, overlay,
+ OVERLAY_DITHER, OVERLAY_ENABLE);
-// ---------------------------------------------------------------------------
+ mOverlay = overlay;
+ mWidth = overlay->w;
+ mHeight = overlay->h;
+ mFormat = overlay->format;
+ mWidthStride = overlay->w_stride;
+ mHeightStride = overlay->h_stride;
-LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
- : LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
-{
-}
+ mOverlayHandle = overlay->getHandleRef(overlay);
+
+ // NOTE: here it's okay to acquire a reference to "this"m as long as
+ // the reference is not released before we leave the ctor.
+ sp<OverlayChanel> chanel = new OverlayChanel(this);
-LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
-{
- unregisterBuffers();
- mOwner = 0;
+ *overlayRef = new OverlayRef(mOverlayHandle, chanel,
+ mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
}
-status_t LayerBuffer::SurfaceBuffer::registerBuffers(
- int w, int h, int hs, int vs,
- PixelFormat format, const sp<IMemoryHeap>& heap)
-{
- LayerBuffer* owner(getOwner());
- if (owner)
- return owner->registerBuffers(w, h, hs, vs, format, heap);
- return NO_INIT;
+LayerBuffer::OverlaySource::~OverlaySource()
+{
}
-void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
+void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
{
- LayerBuffer* owner(getOwner());
- if (owner)
- owner->postBuffer(offset);
+ const Layer::State& front(mLayer.drawingState());
+ const Layer::State& temp(mLayer.currentState());
+ if (temp.sequence != front.sequence) {
+ mVisibilityChanged = true;
+ }
}
-void LayerBuffer::SurfaceBuffer::unregisterBuffers()
+void LayerBuffer::OverlaySource::onVisibilityResolved(
+ const Transform& planeTransform)
{
- LayerBuffer* owner(getOwner());
- if (owner)
- owner->unregisterBuffers();
-}
-
-sp<Overlay> LayerBuffer::SurfaceBuffer::createOverlay(
- uint32_t w, uint32_t h, int32_t format) {
- sp<Overlay> result;
- LayerBuffer* owner(getOwner());
- if (owner)
- result = owner->createOverlay(w, h, format);
- return result;
+ // this code-path must be as tight as possible, it's called each time
+ // the screen is composited.
+ if (UNLIKELY(mOverlay != 0)) {
+ if (mVisibilityChanged) {
+ mVisibilityChanged = false;
+ const Rect& bounds = mLayer.getTransformedBounds();
+ int x = bounds.left;
+ int y = bounds.top;
+ int w = bounds.width();
+ int h = bounds.height();
+
+ // we need a lock here to protect "destroy"
+ Mutex::Autolock _l(mLock);
+ if (mOverlay) {
+ overlay_control_device_t* overlay_dev =
+ mLayer.mFlinger->getOverlayEngine();
+ overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
+ overlay_dev->setParameter(overlay_dev, mOverlay,
+ OVERLAY_TRANSFORM, mLayer.getOrientation());
+ }
+ }
+ }
}
-void LayerBuffer::SurfaceBuffer::disown()
+void LayerBuffer::OverlaySource::serverDestroy()
{
+ // we need a lock here to protect "onVisibilityResolved"
Mutex::Autolock _l(mLock);
- mOwner = 0;
-}
-
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
- int w, int h, int hs, int vs, int f)
- : mCount(0), mHeap(heap)
-{
- NativeBuffer& src(mNativeBuffer);
- src.crop.l = 0;
- src.crop.t = 0;
- src.crop.r = w;
- src.crop.b = h;
- src.img.w = hs ?: w;
- src.img.h = vs ?: h;
- src.img.format = f;
- src.img.offset = offset;
- src.img.base = heap->base();
- src.img.fd = heap->heapID();
- // FIXME: make sure this buffer lies within the heap, in which case, set
- // mHeap to null
-}
-
-LayerBuffer::Buffer::~Buffer()
-{
+ if (mOverlay) {
+ overlay_control_device_t* overlay_dev =
+ mLayer.mFlinger->getOverlayEngine();
+ overlay_dev->destroyOverlay(overlay_dev, mOverlay);
+ mOverlay = 0;
+ }
}
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 3e616f2..63ec2cf 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -33,10 +33,24 @@ namespace android {
class MemoryDealer;
class Region;
-class Overlay;
+class OverlayRef;
class LayerBuffer : public LayerBaseClient
{
+ class Source : public LightRefBase<Source> {
+ public:
+ Source(LayerBuffer& layer);
+ virtual ~Source();
+ virtual void onDraw(const Region& clip) const;
+ virtual void onTransaction(uint32_t flags);
+ virtual void onVisibilityResolved(const Transform& planeTransform);
+ virtual void postBuffer(ssize_t offset);
+ virtual void unregisterBuffers();
+ protected:
+ LayerBuffer& mLayer;
+ };
+
+
public:
static const uint32_t typeInfo;
static const char* const typeID;
@@ -51,39 +65,31 @@ public:
virtual sp<LayerBaseClient::Surface> getSurface() const;
virtual void onDraw(const Region& clip) const;
+ virtual uint32_t doTransaction(uint32_t flags);
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
status_t registerBuffers(int w, int h, int hstride, int vstride,
PixelFormat format, const sp<IMemoryHeap>& heap);
void postBuffer(ssize_t offset);
void unregisterBuffers();
- sp<Overlay> createOverlay(uint32_t w, uint32_t h, int32_t format);
- void invalidate();
- void invalidateLocked();
+ sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format);
+
+ sp<Source> getSource() const;
+ void setNeedsBlending(bool blending);
+ const Rect& getTransformedBounds() const {
+ return mTransformedBounds;
+ }
private:
-
- struct NativeBuffer
- {
+ struct NativeBuffer {
copybit_image_t img;
copybit_rect_t crop;
};
- class Buffer
- {
+ class Buffer : public LightRefBase<Buffer> {
public:
Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
int w, int h, int hs, int vs, int f);
- inline void incStrong(void*) const {
- android_atomic_inc(&mCount);
- }
- inline void decStrong(void*) const {
- int32_t c = android_atomic_dec(&mCount);
- //LOGE_IF(c<1, "Buffer::decStrong() called too many times");
- if (c == 1) {
- delete this;
- }
- }
inline status_t getStatus() const {
return mHeap!=0 ? NO_ERROR : NO_INIT;
}
@@ -91,15 +97,87 @@ private:
return mNativeBuffer;
}
protected:
+ friend class LightRefBase<Buffer>;
Buffer& operator = (const Buffer& rhs);
Buffer(const Buffer& rhs);
~Buffer();
- mutable volatile int32_t mCount;
private:
sp<IMemoryHeap> mHeap;
NativeBuffer mNativeBuffer;
};
+ class BufferSource : public Source {
+ public:
+ BufferSource(LayerBuffer& layer,
+ int w, int h, int hstride, int vstride,
+ PixelFormat format, const sp<IMemoryHeap>& heap);
+ virtual ~BufferSource();
+
+ status_t getStatus() const { return mStatus; }
+ sp<Buffer> getBuffer() const;
+ void setBuffer(const sp<Buffer>& buffer);
+
+ virtual void onDraw(const Region& clip) const;
+ virtual void postBuffer(ssize_t offset);
+ virtual void unregisterBuffers();
+ private:
+ mutable Mutex mLock;
+ sp<IMemoryHeap> mHeap;
+ sp<Buffer> mBuffer;
+ status_t mStatus;
+ int mWidth;
+ int mHeight;
+ int mHStride;
+ int mVStride;
+ int mFormat;
+ mutable sp<MemoryDealer> mTemporaryDealer;
+ mutable LayerBitmap mTempBitmap;
+ mutable GLuint mTextureName;
+ };
+
+ class OverlaySource : public Source {
+ public:
+ OverlaySource(LayerBuffer& layer,
+ sp<OverlayRef>* overlayRef,
+ uint32_t w, uint32_t h, int32_t format);
+ virtual ~OverlaySource();
+ virtual void onTransaction(uint32_t flags);
+ virtual void onVisibilityResolved(const Transform& planeTransform);
+ private:
+ void serverDestroy();
+ class OverlayChanel : public BnOverlay {
+ mutable Mutex mLock;
+ sp<OverlaySource> mSource;
+ virtual void destroy() {
+ sp<OverlaySource> source;
+ { // scope for the lock;
+ Mutex::Autolock _l(mLock);
+ source = mSource;
+ mSource.clear();
+ }
+ if (source != 0) {
+ source->serverDestroy();
+ }
+ }
+ public:
+ OverlayChanel(const sp<OverlaySource>& source)
+ : mSource(source) {
+ }
+ };
+ friend class OverlayChanel;
+ bool mVisibilityChanged;
+
+ overlay_t* mOverlay;
+ overlay_handle_t const *mOverlayHandle;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ int32_t mFormat;
+ int32_t mWidthStride;
+ int32_t mHeightStride;
+ mutable Mutex mLock;
+ };
+
+
class SurfaceBuffer : public LayerBaseClient::Surface
{
public:
@@ -109,7 +187,7 @@ private:
PixelFormat format, const sp<IMemoryHeap>& heap);
virtual void postBuffer(ssize_t offset);
virtual void unregisterBuffers();
- virtual sp<Overlay> createOverlay(
+ virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format);
void disown();
private:
@@ -122,24 +200,14 @@ private:
};
friend class SurfaceFlinger;
- sp<Buffer> getBuffer() const;
- void setBuffer(const sp<Buffer>& buffer);
sp<SurfaceBuffer> getClientSurface() const;
mutable Mutex mLock;
- sp<IMemoryHeap> mHeap;
- sp<Buffer> mBuffer;
- int mWidth;
- int mHeight;
- int mHStride;
- int mVStride;
- int mFormat;
- mutable GLuint mTextureName;
+ sp<Source> mSource;
+
bool mInvalidate;
bool mNeedsBlending;
mutable wp<SurfaceBuffer> mClientSurface;
- mutable sp<MemoryDealer> mTemporaryDealer;
- mutable LayerBitmap mTempBitmap;
};
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerScreenshot.cpp b/libs/surfaceflinger/LayerScreenshot.cpp
index 9b82bad..3e7132b 100644
--- a/libs/surfaceflinger/LayerScreenshot.cpp
+++ b/libs/surfaceflinger/LayerScreenshot.cpp
@@ -23,7 +23,7 @@
#include <utils/Errors.h>
#include <utils/Log.h>
-#include <graphics/SkBitmap.h>
+#include <core/SkBitmap.h>
#include <ui/EGLDisplaySurface.h>
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index e8de21a..4c719e8 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -231,7 +231,7 @@ copybit_device_t* SurfaceFlinger::getBlitEngine() const
return graphicPlane(0).displayHardware().getBlitEngine();
}
-overlay_device_t* SurfaceFlinger::getOverlayEngine() const
+overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
{
return graphicPlane(0).displayHardware().getOverlayEngine();
}
@@ -773,12 +773,12 @@ void SurfaceFlinger::computeVisibleRegions(
coveredRegion.andSelf(aboveCoveredLayers);
// compute this layer's dirty region
- if (layer->invalidate) {
+ if (layer->contentDirty) {
// we need to invalidate the whole region
dirty = visibleRegion;
// as well, as the old visible region
dirty.orSelf(layer->visibleRegionScreen);
- layer->invalidate = false;
+ layer->contentDirty = false;
} else {
// compute the exposed region
// dirty = what's visible now - what's wasn't covered before
@@ -1456,7 +1456,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
"alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
layer->getTypeID(), layer,
s.z, layer->tx(), layer->ty(), s.w, s.h,
- layer->needsBlending(), layer->invalidate,
+ layer->needsBlending(), layer->contentDirty,
s.alpha, s.flags,
s.transform[0], s.transform[1],
s.transform[2], s.transform[3]);
@@ -1474,22 +1474,6 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
}
result.append(buffer);
buffer[0] = 0;
- /*** LayerBuffer ***/
- LayerBuffer* const lbuf =
- LayerBase::dynamicCast<LayerBuffer*>((LayerBase*)layer);
- if (lbuf) {
- sp<LayerBuffer::Buffer> lbb(lbuf->getBuffer());
- if (lbb != 0) {
- const LayerBuffer::NativeBuffer& nbuf(lbb->getBuffer());
- snprintf(buffer, SIZE,
- " "
- "mBuffer={w=%u, h=%u, f=%d, offset=%u, base=%p, fd=%d }\n",
- nbuf.img.w, nbuf.img.h, nbuf.img.format, nbuf.img.offset,
- nbuf.img.base, nbuf.img.fd);
- }
- }
- result.append(buffer);
- buffer[0] = 0;
/*** Layer ***/
Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
if (l) {
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 92021d0..a242f1a 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -180,7 +180,7 @@ public:
}
copybit_device_t* getBlitEngine() const;
- overlay_device_t* getOverlayEngine() const;
+ overlay_control_device_t* getOverlayEngine() const;
private:
friend class BClient;
@@ -382,24 +382,16 @@ private:
// ---------------------------------------------------------------------------
-class FreezeLock {
+class FreezeLock : public LightRefBase<FreezeLock> {
SurfaceFlinger* mFlinger;
- mutable volatile int32_t mCount;
public:
FreezeLock(SurfaceFlinger* flinger)
- : mFlinger(flinger), mCount(0) {
+ : mFlinger(flinger) {
mFlinger->incFreezeCount();
}
~FreezeLock() {
mFlinger->decFreezeCount();
}
- inline void incStrong(void*) const {
- android_atomic_inc(&mCount);
- }
- inline void decStrong(void*) const {
- if (android_atomic_dec(&mCount) == 1)
- delete this;
- }
};
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
index 2f617c4..0b4835e 100644
--- a/libs/surfaceflinger/Transform.h
+++ b/libs/surfaceflinger/Transform.h
@@ -25,7 +25,7 @@
#include <GLES/gl.h>
-#include <corecg/SkMatrix.h>
+#include <core/SkMatrix.h>
namespace android {
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 9527009..4a325ac 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -136,6 +136,18 @@ sp<ICamera> Camera::remote()
return mCamera;
}
+status_t Camera::lock()
+{
+ if (mCamera != 0) return mCamera->lock();
+ return NO_INIT;
+}
+
+status_t Camera::unlock()
+{
+ if (mCamera != 0) return mCamera->unlock();
+ return NO_INIT;
+}
+
// pass the buffered ISurface to the camera service
status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
{
@@ -172,6 +184,13 @@ void Camera::stopPreview()
mCamera->stopPreview();
}
+// get preview state
+bool Camera::previewEnabled()
+{
+ LOGV("previewEnabled");
+ return mCamera->previewEnabled();
+}
+
status_t Camera::autoFocus()
{
LOGV("autoFocus");
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
index 6a2dc6b..7b0922e 100644
--- a/libs/ui/ICamera.cpp
+++ b/libs/ui/ICamera.cpp
@@ -35,7 +35,10 @@ enum {
TAKE_PICTURE,
SET_PARAMETERS,
GET_PARAMETERS,
- CONNECT
+ CONNECT,
+ LOCK,
+ UNLOCK,
+ PREVIEW_ENABLED
};
class BpCamera: public BpInterface<ICamera>
@@ -96,6 +99,16 @@ public:
remote()->transact(STOP_PREVIEW, data, &reply);
}
+ // check preview state
+ bool previewEnabled()
+ {
+ LOGV("previewEnabled");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+ remote()->transact(PREVIEW_ENABLED, data, &reply);
+ return reply.readInt32();
+ }
+
// auto focus
status_t autoFocus()
{
@@ -146,6 +159,20 @@ public:
remote()->transact(CONNECT, data, &reply);
return reply.readInt32();
}
+ virtual status_t lock()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+ remote()->transact(LOCK, data, &reply);
+ return reply.readInt32();
+ }
+ virtual status_t unlock()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+ remote()->transact(UNLOCK, data, &reply);
+ return reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
@@ -194,6 +221,12 @@ status_t BnCamera::onTransact(
stopPreview();
return NO_ERROR;
} break;
+ case PREVIEW_ENABLED: {
+ LOGV("PREVIEW_ENABLED");
+ CHECK_INTERFACE(ICamera, data, reply);
+ reply->writeInt32(previewEnabled());
+ return NO_ERROR;
+ } break;
case AUTO_FOCUS: {
LOGV("AUTO_FOCUS");
CHECK_INTERFACE(ICamera, data, reply);
@@ -225,6 +258,16 @@ status_t BnCamera::onTransact(
reply->writeInt32(connect(cameraClient));
return NO_ERROR;
} break;
+ case LOCK: {
+ CHECK_INTERFACE(ICamera, data, reply);
+ reply->writeInt32(lock());
+ return NO_ERROR;
+ } break;
+ case UNLOCK: {
+ CHECK_INTERFACE(ICamera, data, reply);
+ reply->writeInt32(unlock());
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/ui/IOverlay.cpp b/libs/ui/IOverlay.cpp
index 59d1ea0..fed47c2 100644
--- a/libs/ui/IOverlay.cpp
+++ b/libs/ui/IOverlay.cpp
@@ -27,7 +27,6 @@ namespace android {
enum {
DESTROY = IBinder::FIRST_CALL_TRANSACTION, // one-way transaction
- SWAP_BUFFERS,
};
class BpOverlay : public BpInterface<IOverlay>
@@ -44,14 +43,6 @@ public:
data.writeInterfaceToken(IOverlay::getInterfaceDescriptor());
remote()->transact(DESTROY, data, &reply, IBinder::FLAG_ONEWAY);
}
-
- virtual ssize_t swapBuffers()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IOverlay::getInterfaceDescriptor());
- remote()->transact(SWAP_BUFFERS, data, &reply);
- return reply.readInt32();
- }
};
IMPLEMENT_META_INTERFACE(Overlay, "android.ui.IOverlay");
@@ -73,12 +64,6 @@ status_t BnOverlay::onTransact(
destroy();
return NO_ERROR;
} break;
- case SWAP_BUFFERS: {
- CHECK_INTERFACE(IOverlay, data, reply);
- ssize_t offset = swapBuffers();
- reply->writeInt32(offset);
- return NO_ERROR;
- } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
index c1c9596..54f78fe 100644
--- a/libs/ui/ISurface.cpp
+++ b/libs/ui/ISurface.cpp
@@ -73,7 +73,7 @@ public:
remote()->transact(UNREGISTER_BUFFERS, data, &reply);
}
- virtual sp<Overlay> createOverlay(
+ virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format)
{
Parcel data, reply;
@@ -82,7 +82,7 @@ public:
data.writeInt32(h);
data.writeInt32(format);
remote()->transact(CREATE_OVERLAY, data, &reply);
- return Overlay::readFromParcel(reply);
+ return OverlayRef::readFromParcel(reply);
}
};
@@ -128,8 +128,8 @@ status_t BnSurface::onTransact(
int w = data.readInt32();
int h = data.readInt32();
int f = data.readInt32();
- sp<Overlay> o = createOverlay(w, h, w);
- return Overlay::writeToParcel(reply, o);
+ sp<OverlayRef> o = createOverlay(w, h, w);
+ return OverlayRef::writeToParcel(reply, o);
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index 2267c3e..a79950c 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -16,86 +16,114 @@
#include <utils/IMemory.h>
#include <utils/Parcel.h>
+#include <utils/Errors.h>
+#include <utils/MemoryHeapBase.h>
#include <ui/IOverlay.h>
#include <ui/Overlay.h>
+#include <hardware/overlay.h>
+
namespace android {
-Overlay::Overlay(overlay_handle_t* handle,
- const sp<IOverlay>& o, const sp<IMemoryHeap>& heap,
- uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
- : mOverlay(o), mHeap(heap), mCurrentBufferOffset(0), mOverlayHandle(handle),
- mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs)
+Overlay::Overlay(const sp<OverlayRef>& overlayRef)
+ : mOverlayRef(overlayRef), mOverlayData(0), mStatus(NO_INIT)
{
+ mOverlayData = NULL;
+ hw_module_t const* module;
+ if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
+ if (overlay_data_open(module, &mOverlayData) == NO_ERROR) {
+ mStatus = mOverlayData->initialize(mOverlayData,
+ overlayRef->mOverlayHandle);
+ }
+ }
}
-Overlay::Overlay(overlay_t* overlay,
- const sp<IOverlay>& o, const sp<IMemoryHeap>& heap)
- : mOverlay(o), mHeap(heap)
-{
- mCurrentBufferOffset = 0;
- mOverlayHandle = overlay->getHandleRef(overlay);
- mWidth = overlay->w;
- mHeight = overlay->h;
- mFormat = overlay->format;
- mWidthStride = overlay->w_stride;
- mHeightStride = overlay->h_stride;
+Overlay::~Overlay() {
+ if (mOverlayData) {
+ overlay_data_close(mOverlayData);
+ }
}
-
-Overlay::~Overlay() {
+overlay_buffer_t Overlay::dequeueBuffer()
+{
+ return mOverlayData->dequeueBuffer(mOverlayData);
}
-void Overlay::destroy() {
- mOverlay->destroy();
+int Overlay::queueBuffer(overlay_buffer_t buffer)
+{
+ return mOverlayData->queueBuffer(mOverlayData, buffer);
}
-status_t Overlay::swapBuffers() {
- ssize_t result = mOverlay->swapBuffers();
- if (result < 0)
- return status_t(result);
- mCurrentBufferOffset = result;
- return NO_ERROR;
+void* Overlay::getBufferAddress(overlay_buffer_t buffer)
+{
+ return mOverlayData->getBufferAddress(mOverlayData, buffer);
}
-overlay_handle_t const* Overlay::getHandleRef() const {
- return mOverlayHandle;
+void Overlay::destroy() {
+ mOverlayRef->mOverlayChanel->destroy();
}
-size_t Overlay::getBufferOffset() const {
- return mCurrentBufferOffset;
+status_t Overlay::getStatus() const {
+ return mStatus;
}
-sp<IMemoryHeap> Overlay::getHeap() const {
- return mHeap;
+overlay_handle_t const* Overlay::getHandleRef() const {
+ return mOverlayRef->mOverlayHandle;
}
uint32_t Overlay::getWidth() const {
- return mWidth;
+ return mOverlayRef->mWidth;
}
uint32_t Overlay::getHeight() const {
- return mHeight;
+ return mOverlayRef->mHeight;
}
int32_t Overlay::getFormat() const {
- return mFormat;
+ return mOverlayRef->mFormat;
}
int32_t Overlay::getWidthStride() const {
- return mWidthStride;
+ return mOverlayRef->mWidthStride;
}
int32_t Overlay::getHeightStride() const {
- return mHeightStride;
+ return mOverlayRef->mHeightStride;
+}
+// ----------------------------------------------------------------------------
+
+OverlayRef::OverlayRef()
+ : mOverlayHandle(0),
+ mWidth(0), mHeight(0), mFormat(0), mWidthStride(0), mHeightStride(0),
+ mOwnHandle(true)
+{
+}
+
+OverlayRef::OverlayRef(overlay_handle_t const* handle, const sp<IOverlay>& chanel,
+ uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
+ : mOverlayHandle(handle), mOverlayChanel(chanel),
+ mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs),
+ mOwnHandle(false)
+{
+}
+
+OverlayRef::~OverlayRef()
+{
+ if (mOwnHandle) {
+ /* FIXME: handles should be promoted to "real" API and be handled by
+ * the framework */
+ for (int i=0 ; i<mOverlayHandle->numFds ; i++) {
+ close(mOverlayHandle->fds[i]);
+ }
+ free((void*)mOverlayHandle);
+ }
}
-sp<Overlay> Overlay::readFromParcel(const Parcel& data) {
- sp<Overlay> result;
+sp<OverlayRef> OverlayRef::readFromParcel(const Parcel& data) {
+ sp<OverlayRef> result;
sp<IOverlay> overlay = IOverlay::asInterface(data.readStrongBinder());
if (overlay != NULL) {
- sp<IMemoryHeap> heap = IMemoryHeap::asInterface(data.readStrongBinder());
uint32_t w = data.readInt32();
uint32_t h = data.readInt32();
uint32_t f = data.readInt32();
@@ -111,15 +139,21 @@ sp<Overlay> Overlay::readFromParcel(const Parcel& data) {
handle->fds[i] = data.readFileDescriptor();
for (int i=0 ; i<numint ; i++)
handle->data[i] = data.readInt32();
- result = new Overlay(handle, overlay, heap, w, h, f, ws, hs);
+ result = new OverlayRef();
+ result->mOverlayHandle = handle;
+ result->mOverlayChanel = overlay;
+ result->mWidth = w;
+ result->mHeight = h;
+ result->mFormat = f;
+ result->mWidthStride = ws;
+ result->mHeightStride = hs;
}
return result;
}
-status_t Overlay::writeToParcel(Parcel* reply, const sp<Overlay>& o) {
+status_t OverlayRef::writeToParcel(Parcel* reply, const sp<OverlayRef>& o) {
if (o != NULL) {
- reply->writeStrongBinder(o->mOverlay->asBinder());
- reply->writeStrongBinder(o->mHeap->asBinder());
+ reply->writeStrongBinder(o->mOverlayChanel->asBinder());
reply->writeInt32(o->mWidth);
reply->writeInt32(o->mHeight);
reply->writeInt32(o->mFormat);
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 3e07f2b..26e694a 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -21,8 +21,6 @@
#include <utils/Debug.h>
#include <utils/String8.h>
#include <ui/Region.h>
-#include <corecg/SkRegion.h>
-#include <corecg/SkRect.h>
namespace android {
diff --git a/libs/utils/MemoryHeapBase.cpp b/libs/utils/MemoryHeapBase.cpp
index 59963c9..8251728 100644
--- a/libs/utils/MemoryHeapBase.cpp
+++ b/libs/utils/MemoryHeapBase.cpp
@@ -119,19 +119,24 @@ status_t MemoryHeapBase::mapfd(int fd, size_t size)
// if it didn't work, let mmap() fail.
}
- void* base = (uint8_t*)mmap(0, size,
- PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (base == MAP_FAILED) {
- LOGE("mmap(fd=%d, size=%u) failed (%s)",
- fd, uint32_t(size), strerror(errno));
- close(fd);
- return -errno;
+ if ((mFlags & DONT_MAP_LOCALLY) == 0) {
+ void* base = (uint8_t*)mmap(0, size,
+ PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (base == MAP_FAILED) {
+ LOGE("mmap(fd=%d, size=%u) failed (%s)",
+ fd, uint32_t(size), strerror(errno));
+ close(fd);
+ return -errno;
+ }
+ //LOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
+ mBase = base;
+ mNeedUnmap = true;
+ } else {
+ mBase = 0; // not MAP_FAILED
+ mNeedUnmap = false;
}
- //LOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
mFD = fd;
- mBase = base;
mSize = size;
- mNeedUnmap = true;
return NO_ERROR;
}