diff options
61 files changed, 2494 insertions, 1443 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index b63e97f..df59dcf 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -309,7 +309,7 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client) oldClient = mCameraClient; // did the client actually change? - if (client->asBinder() == mCameraClient->asBinder()) { + if ((mCameraClient != NULL) && (client->asBinder() == mCameraClient->asBinder())) { LOGD("Connect to the same client"); return NO_ERROR; } @@ -683,22 +683,30 @@ void CameraService::Client::stopPreview() { LOGD("stopPreview (pid %d)", getCallingPid()); - Mutex::Autolock lock(mLock); - if (checkPid() != NO_ERROR) return; + // hold main lock during state transition + { + Mutex::Autolock lock(mLock); + if (checkPid() != NO_ERROR) return; - if (mHardware == 0) { - LOGE("mHardware is NULL, returning."); - return; - } + if (mHardware == 0) { + LOGE("mHardware is NULL, returning."); + return; + } - mHardware->stopPreview(); - mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME); - LOGD("stopPreview(), hardware stopped OK"); + mHardware->stopPreview(); + mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME); + LOGD("stopPreview(), hardware stopped OK"); - if (mSurface != 0 && !mUseOverlay) { - mSurface->unregisterBuffers(); + if (mSurface != 0 && !mUseOverlay) { + mSurface->unregisterBuffers(); + } + } + + // hold preview buffer lock + { + Mutex::Autolock lock(mPreviewLock); + mPreviewBuffer.clear(); } - mPreviewBuffer.clear(); } // stop recording mode @@ -706,24 +714,31 @@ void CameraService::Client::stopRecording() { LOGD("stopRecording (pid %d)", getCallingPid()); - Mutex::Autolock lock(mLock); - if (checkPid() != NO_ERROR) return; + // hold main lock during state transition + { + Mutex::Autolock lock(mLock); + if (checkPid() != NO_ERROR) return; - if (mHardware == 0) { - LOGE("mHardware is NULL, returning."); - return; - } + if (mHardware == 0) { + LOGE("mHardware is NULL, returning."); + return; + } - if (mMediaPlayerBeep.get() != NULL) { - mMediaPlayerBeep->seekTo(0); - mMediaPlayerBeep->start(); - } + if (mMediaPlayerBeep.get() != NULL) { + mMediaPlayerBeep->seekTo(0); + mMediaPlayerBeep->start(); + } - mHardware->stopRecording(); - mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME); - LOGD("stopRecording(), hardware stopped OK"); + mHardware->stopRecording(); + mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME); + LOGD("stopRecording(), hardware stopped OK"); + } - mPreviewBuffer.clear(); + // hold preview buffer lock + { + Mutex::Autolock lock(mPreviewLock); + mPreviewBuffer.clear(); + } } // release a recording frame @@ -865,7 +880,11 @@ status_t CameraService::Client::takePicture() } // snapshot taken -void CameraService::Client::handleShutter() +void CameraService::Client::handleShutter( + image_rect_type *size // The width and height of yuv picture for + // registerBuffer. If this is NULL, use the picture + // size from parameters. +) { // Play shutter sound. if (mMediaPlayerClick.get() != NULL) { @@ -878,7 +897,10 @@ void CameraService::Client::handleShutter() mSurface->unregisterBuffers(); } - mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); + sp<ICameraClient> c = mCameraClient; + if (c != NULL) { + c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); + } mHardware->disableMsgType(CAMERA_MSG_SHUTTER); // It takes some time before yuvPicture callback to be called. @@ -886,12 +908,21 @@ void CameraService::Client::handleShutter() if (mSurface != 0 && !mUseOverlay) { int w, h; CameraParameters params(mHardware->getParameters()); - params.getPictureSize(&w, &h); uint32_t transform = 0; if (params.getOrientation() == CameraParameters::CAMERA_ORIENTATION_PORTRAIT) { LOGV("portrait mode"); transform = ISurface::BufferHeap::ROT_90; } + + if (size == NULL) { + params.getPictureSize(&w, &h); + } else { + w = size->width; + h = size->height; + w &= ~1; + h &= ~1; + LOGD("Snapshot image width=%d, height=%d", w, h); + } ISurface::BufferHeap buffers(w, h, w, h, PIXEL_FORMAT_YCbCr_420_SP, transform, 0, mHardware->getRawHeap()); @@ -932,31 +963,38 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) } } - // Is the callback enabled or not? - if (!(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)) { + // local copy of the callback flags + int flags = mPreviewCallbackFlag; + + // is callback enabled? + if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) { // If the enable bit is off, the copy-out and one-shot bits are ignored LOGV("frame callback is diabled"); return; } - // Is the received frame copied out or not? - if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { - LOGV("frame is copied out"); - copyFrameAndPostCopiedFrame(heap, offset, size); - } else { - LOGV("frame is directly sent out without copying"); - mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem); - } + // hold a strong pointer to the client + sp<ICameraClient> c = mCameraClient; - // Is this is one-shot only? - if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) { - LOGV("One-shot only, thus clear the bits and disable frame callback"); + // clear callback flags if no client or one-shot mode + if ((c == NULL) || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) { + LOGV("Disable preview callback"); mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK | FRAME_CALLBACK_FLAG_ENABLE_MASK); + // TODO: Shouldn't we use this API for non-overlay hardware as well? if (mUseOverlay) mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME); } + + // Is the received frame copied out or not? + if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { + LOGV("frame is copied"); + copyFrameAndPostCopiedFrame(c, heap, offset, size); + } else { + LOGV("frame is forwarded"); + c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem); + } } // picture callback - postview image ready @@ -972,7 +1010,10 @@ void CameraService::Client::handlePostview(const sp<IMemory>& mem) } #endif - mCameraClient->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem); + sp<ICameraClient> c = mCameraClient; + if (c != NULL) { + c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem); + } mHardware->disableMsgType(CAMERA_MSG_POSTVIEW_FRAME); } @@ -997,7 +1038,10 @@ void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) mSurface->postBuffer(offset); } - mCameraClient->dataCallback(CAMERA_MSG_RAW_IMAGE, mem); + sp<ICameraClient> c = mCameraClient; + if (c != NULL) { + c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem); + } mHardware->disableMsgType(CAMERA_MSG_RAW_IMAGE); } @@ -1014,7 +1058,10 @@ void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) } #endif - mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem); + sp<ICameraClient> c = mCameraClient; + if (c != NULL) { + c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem); + } mHardware->disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE); } @@ -1029,10 +1076,14 @@ void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1, int32_ switch (msgType) { case CAMERA_MSG_SHUTTER: - client->handleShutter(); + // ext1 is the dimension of the yuv picture. + client->handleShutter((image_rect_type *)ext1); break; default: - client->mCameraClient->notifyCallback(msgType, ext1, ext2); + sp<ICameraClient> c = client->mCameraClient; + if (c != NULL) { + c->notifyCallback(msgType, ext1, ext2); + } break; } @@ -1053,10 +1104,13 @@ void CameraService::Client::dataCallback(int32_t msgType, const sp<IMemory>& dat return; } + sp<ICameraClient> c = client->mCameraClient; if (dataPtr == NULL) { LOGE("Null data returned in data callback"); - client->mCameraClient->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); - client->mCameraClient->dataCallback(msgType, NULL); + if (c != NULL) { + c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); + c->dataCallback(msgType, NULL); + } return; } @@ -1074,7 +1128,9 @@ void CameraService::Client::dataCallback(int32_t msgType, const sp<IMemory>& dat client->handleCompressedPicture(dataPtr); break; default: - client->mCameraClient->dataCallback(msgType, dataPtr); + if (c != NULL) { + c->dataCallback(msgType, dataPtr); + } break; } @@ -1095,15 +1151,20 @@ void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, int32_t msg if (client == 0) { return; } + sp<ICameraClient> c = client->mCameraClient; if (dataPtr == NULL) { LOGE("Null data returned in data with timestamp callback"); - client->mCameraClient->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); - client->mCameraClient->dataCallbackTimestamp(0, msgType, NULL); + if (c != NULL) { + c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); + c->dataCallbackTimestamp(0, msgType, NULL); + } return; } - client->mCameraClient->dataCallbackTimestamp(timestamp, msgType, dataPtr); + if (c != NULL) { + c->dataCallbackTimestamp(timestamp, msgType, dataPtr); + } #if DEBUG_CLIENT_REFERENCES if (client->getStrongCount() == 1) { @@ -1161,32 +1222,40 @@ status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t a return mHardware->sendCommand(cmd, arg1, arg2); } -void CameraService::Client::copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size) +void CameraService::Client::copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client, + const sp<IMemoryHeap>& heap, size_t offset, size_t size) { LOGV("copyFrameAndPostCopiedFrame"); // It is necessary to copy out of pmem before sending this to // the callback. For efficiency, reuse the same MemoryHeapBase // provided it's big enough. Don't allocate the memory or // perform the copy if there's no callback. - if (mPreviewBuffer == 0) { - mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); - } else if (size > mPreviewBuffer->virtualSize()) { - mPreviewBuffer.clear(); - mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); + + // hold the preview lock while we grab a reference to the preview buffer + sp<MemoryHeapBase> previewBuffer; + { + Mutex::Autolock lock(mPreviewLock); + if (mPreviewBuffer == 0) { + mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); + } else if (size > mPreviewBuffer->virtualSize()) { + mPreviewBuffer.clear(); + mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); + } if (mPreviewBuffer == 0) { LOGE("failed to allocate space for preview buffer"); return; } + previewBuffer = mPreviewBuffer; } - memcpy(mPreviewBuffer->base(), + memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size); - sp<MemoryBase> frame = new MemoryBase(mPreviewBuffer, 0, size); + sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size); if (frame == 0) { LOGE("failed to allocate space for frame callback"); return; } - mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame); + client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame); } status_t CameraService::dump(int fd, const Vector<String16>& args) diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h index 2e3597f..3e3e54f 100644 --- a/camera/libcameraservice/CameraService.h +++ b/camera/libcameraservice/CameraService.h @@ -23,10 +23,9 @@ #include <ui/CameraHardwareInterface.h> #include <ui/Camera.h> -class android::MemoryHeapBase; - namespace android { +class MemoryHeapBase; class MediaPlayer; // ---------------------------------------------------------------------------- @@ -146,12 +145,13 @@ private: static sp<Client> getClientFromCookie(void* user); void handlePreviewData(const sp<IMemory>&); - void handleShutter(); + void handleShutter(image_rect_type *image); void handlePostview(const sp<IMemory>&); void handleRawPicture(const sp<IMemory>&); void handleCompressedPicture(const sp<IMemory>&); - void copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size); + void copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client, + const sp<IMemoryHeap>& heap, size_t offset, size_t size); // camera operation mode enum camera_mode { @@ -181,7 +181,6 @@ private: mutable Condition mReady; sp<CameraService> mCameraService; sp<ISurface> mSurface; - sp<MemoryHeapBase> mPreviewBuffer; int mPreviewCallbackFlag; sp<MediaPlayer> mMediaPlayerClick; @@ -197,6 +196,9 @@ private: sp<OverlayRef> mOverlayRef; int mOverlayW; int mOverlayH; + + mutable Mutex mPreviewLock; + sp<MemoryHeapBase> mPreviewBuffer; }; // ---------------------------------------------------------------------------- diff --git a/include/binder/MemoryHeapBase.h b/include/binder/MemoryHeapBase.h index 435540e..d793c24 100644 --- a/include/binder/MemoryHeapBase.h +++ b/include/binder/MemoryHeapBase.h @@ -35,7 +35,8 @@ public: MAP_ONCE = IMemoryHeap::MAP_ONCE, // memory won't be mapped locally, but will be mapped in the remote // process. - DONT_MAP_LOCALLY = 0x00000100 + DONT_MAP_LOCALLY = 0x00000100, + NO_CACHING = 0x00000200 }; /* diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h index 67c2dd8..26cde38 100644 --- a/include/private/opengles/gl_context.h +++ b/include/private/opengles/gl_context.h @@ -32,6 +32,8 @@ #include <GLES/gl.h> #include <GLES/glext.h> +struct android_native_buffer_t; + namespace android { const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10; @@ -602,7 +604,7 @@ struct copybits_context_t { copybit_device_t* blitEngine; int32_t minScale; int32_t maxScale; - buffer_handle_t drawSurfaceBuffer; + android_native_buffer_t* drawSurfaceBuffer; }; struct ogles_context_t { diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h index 926fddb..8d76533 100644 --- a/include/private/ui/RegionHelper.h +++ b/include/private/ui/RegionHelper.h @@ -86,7 +86,7 @@ public: rasterizer(current); } } - } while(!spannerInner.isDone()); + } while(!spannerInner.isDone()); } while(!spanner.isDone()); } @@ -220,18 +220,21 @@ private: } inline void prepare(int inside) { - SpannerBase::lhs_head = lhs.rects->left + lhs.dx; - SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; - SpannerBase::rhs_head = rhs.rects->left + rhs.dx; - SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; if (inside == SpannerBase::lhs_before_rhs) { + SpannerBase::lhs_head = lhs.rects->left + lhs.dx; + SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; SpannerBase::rhs_head = max_value; SpannerBase::rhs_tail = max_value; } else if (inside == SpannerBase::lhs_after_rhs) { SpannerBase::lhs_head = max_value; SpannerBase::lhs_tail = max_value; + SpannerBase::rhs_head = rhs.rects->left + rhs.dx; + SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; } else { - // use both spans + SpannerBase::lhs_head = lhs.rects->left + lhs.dx; + SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; + SpannerBase::rhs_head = rhs.rects->left + rhs.dx; + SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; } } diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h index af40f31..240c134 100644 --- a/include/ui/CameraHardwareInterface.h +++ b/include/ui/CameraHardwareInterface.h @@ -25,6 +25,15 @@ #include <ui/Overlay.h> namespace android { +/** + * The size of image for display. + */ +typedef struct image_rect_struct +{ + uint32_t width; /* Image width */ + uint32_t height; /* Image height */ +} image_rect_type; + typedef void (*notify_callback)(int32_t msgType, int32_t ext1, diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index 8897f03..b9c491b 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -66,7 +66,11 @@ public: GraphicBuffer(); // creates w * h buffer - GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t ssage); + GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage); + + // create a buffer from an existing handle + GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, + uint32_t stride, native_handle_t* handle, bool keepOwnership); // return status status_t initCheck() const; @@ -89,14 +93,22 @@ public: void setIndex(int index); int getIndex() const; + void setVerticalStride(uint32_t vstride); + uint32_t getVerticalStride() const; protected: GraphicBuffer(const Parcel& reply); virtual ~GraphicBuffer(); + enum { + ownNone = 0, + ownHandle = 1, + ownData = 2, + }; + inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; } inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; } - bool mOwner; + uint8_t mOwner; private: friend class Surface; diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 70303cd..008c297 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -109,7 +109,7 @@ private: ~SurfaceControl(); - status_t validate(SharedClient const* cblk) const; + status_t validate() const; void destroy(); sp<SurfaceComposerClient> mClient; @@ -190,7 +190,7 @@ private: status_t getBufferLocked(int index, int usage); - status_t validate(SharedClient const* cblk) const; + status_t validate() const; inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; } inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; } diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index 17ccad6..49145e8 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -1272,7 +1272,7 @@ struct ResTable_config if (version || o.version) { if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) { - return (sdkVersion); + return (sdkVersion > o.sdkVersion); } if ((minorVersion != o.minorVersion) && @@ -1384,7 +1384,7 @@ struct ResTable_config } if (version != 0) { if (settings.sdkVersion != 0 && sdkVersion != 0 - && sdkVersion != settings.sdkVersion) { + && sdkVersion > settings.sdkVersion) { return false; } if (settings.minorVersion != 0 && minorVersion != 0 diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp index ba8b322..daec6e8 100644 --- a/libs/audioflinger/AudioFlinger.cpp +++ b/libs/audioflinger/AudioFlinger.cpp @@ -482,38 +482,17 @@ status_t AudioFlinger::setStreamVolume(int stream, float value, int output) } } - status_t ret = NO_ERROR; - - if (stream == AudioSystem::VOICE_CALL || - stream == AudioSystem::BLUETOOTH_SCO) { - float hwValue; - if (stream == AudioSystem::VOICE_CALL) { - hwValue = (float)AudioSystem::logToLinear(value)/100.0f; - // offset value to reflect actual hardware volume that never reaches 0 - // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java) - value = 0.01 + 0.99 * value; - } else { // (type == AudioSystem::BLUETOOTH_SCO) - hwValue = 1.0f; - } - - AutoMutex lock(mHardwareLock); - mHardwareStatus = AUDIO_SET_VOICE_VOLUME; - ret = mAudioHardware->setVoiceVolume(hwValue); - mHardwareStatus = AUDIO_HW_IDLE; - - } - mStreamTypes[stream].volume = value; if (thread == NULL) { - for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) + for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) { mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value); - + } } else { thread->setStreamVolume(stream, value); } - return ret; + return NO_ERROR; } status_t AudioFlinger::setStreamMute(int stream, bool muted) @@ -553,11 +532,6 @@ float AudioFlinger::streamVolume(int stream, int output) const volume = mStreamTypes[stream].volume; } - // remove correction applied by setStreamVolume() - if (stream == AudioSystem::VOICE_CALL) { - volume = (volume - 0.01) / 0.99 ; - } - return volume; } @@ -644,6 +618,21 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int cha return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount); } +status_t AudioFlinger::setVoiceVolume(float value) +{ + // check calling permissions + if (!settingsAllowed()) { + return PERMISSION_DENIED; + } + + AutoMutex lock(mHardwareLock); + mHardwareStatus = AUDIO_SET_VOICE_VOLUME; + status_t ret = mAudioHardware->setVoiceVolume(value); + mHardwareStatus = AUDIO_HW_IDLE; + + return ret; +} + void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) { @@ -685,32 +674,13 @@ void AudioFlinger::binderDied(const wp<IBinder>& who) { } // audioConfigChanged_l() must be called with AudioFlinger::mLock held -void AudioFlinger::audioConfigChanged_l(int event, const sp<ThreadBase>& thread, void *param2) { - int ioHandle = 0; - - for (size_t i = 0; i < mPlaybackThreads.size(); i++) { - if (mPlaybackThreads.valueAt(i) == thread) { - ioHandle = mPlaybackThreads.keyAt(i); - break; - } - } - if (ioHandle == 0) { - for (size_t i = 0; i < mRecordThreads.size(); i++) { - if (mRecordThreads.valueAt(i) == thread) { - ioHandle = mRecordThreads.keyAt(i); - break; - } - } - } - - if (ioHandle != 0) { - size_t size = mNotificationClients.size(); - for (size_t i = 0; i < size; i++) { - sp<IBinder> binder = mNotificationClients.itemAt(i); - LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get()); - sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder); - client->ioConfigChanged(event, ioHandle, param2); - } +void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) { + size_t size = mNotificationClients.size(); + for (size_t i = 0; i < size; i++) { + sp<IBinder> binder = mNotificationClients.itemAt(i); + LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get()); + sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder); + client->ioConfigChanged(event, ioHandle, param2); } } @@ -723,10 +693,10 @@ void AudioFlinger::removeClient_l(pid_t pid) // ---------------------------------------------------------------------------- -AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger) +AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id) : Thread(false), mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0), - mFormat(0), mFrameSize(1), mStandby(false) + mFormat(0), mFrameSize(1), mStandby(false), mId(id), mExiting(false) { } @@ -745,6 +715,7 @@ void AudioFlinger::ThreadBase::exit() LOGV("ThreadBase::exit"); { AutoMutex lock(&mLock); + mExiting = true; requestExit(); mWaitWorkCV.signal(); } @@ -826,11 +797,63 @@ void AudioFlinger::ThreadBase::processConfigEvents() mLock.unlock(); } +status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + bool locked = tryLock(mLock); + if (!locked) { + snprintf(buffer, SIZE, "thread %p maybe dead locked\n", this); + write(fd, buffer, strlen(buffer)); + } + + snprintf(buffer, SIZE, "standby: %d\n", mStandby); + result.append(buffer); + snprintf(buffer, SIZE, "Sample rate: %d\n", mSampleRate); + result.append(buffer); + snprintf(buffer, SIZE, "Frame count: %d\n", mFrameCount); + result.append(buffer); + snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount); + result.append(buffer); + snprintf(buffer, SIZE, "Format: %d\n", mFormat); + result.append(buffer); + snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize); + result.append(buffer); + + snprintf(buffer, SIZE, "\nPending setParameters commands: \n"); + result.append(buffer); + result.append(" Index Command"); + for (size_t i = 0; i < mNewParameters.size(); ++i) { + snprintf(buffer, SIZE, "\n %02d ", i); + result.append(buffer); + result.append(mNewParameters[i]); + } + + snprintf(buffer, SIZE, "\n\nPending config events: \n"); + result.append(buffer); + snprintf(buffer, SIZE, " Index event param\n"); + result.append(buffer); + for (size_t i = 0; i < mConfigEvents.size(); i++) { + snprintf(buffer, SIZE, " %02d %02d %d\n", i, mConfigEvents[i]->mEvent, mConfigEvents[i]->mParam); + result.append(buffer); + } + result.append("\n"); + + write(fd, result.string(), result.size()); + + if (locked) { + mLock.unlock(); + } + return NO_ERROR; +} + // ---------------------------------------------------------------------------- -AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output) - : ThreadBase(audioFlinger), +AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id) + : ThreadBase(audioFlinger, id), mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false) { @@ -867,7 +890,7 @@ status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16> snprintf(buffer, SIZE, "Output thread %p tracks\n", this); result.append(buffer); - result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n"); + result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n"); for (size_t i = 0; i < mTracks.size(); ++i) { sp<Track> track = mTracks[i]; if (track != 0) { @@ -878,7 +901,7 @@ status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16> snprintf(buffer, SIZE, "Output thread %p active tracks\n", this); result.append(buffer); - result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n"); + result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n"); for (size_t i = 0; i < mActiveTracks.size(); ++i) { wp<Track> wTrack = mActiveTracks[i]; if (wTrack != 0) { @@ -899,7 +922,7 @@ status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String char buffer[SIZE]; String8 result; - snprintf(buffer, SIZE, "Output thread %p internals\n", this); + snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this); result.append(buffer); snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime)); result.append(buffer); @@ -909,9 +932,10 @@ status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String result.append(buffer); snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite); result.append(buffer); - snprintf(buffer, SIZE, "standby: %d\n", mStandby); - result.append(buffer); write(fd, result.string(), result.size()); + + dumpBase(fd, args); + return NO_ERROR; } @@ -976,7 +1000,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra Mutex::Autolock _l(mLock); track = new Track(this, client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer); - if (track->getCblk() == NULL) { + if (track->getCblk() == NULL || track->name() < 0) { lStatus = NO_MEMORY; goto Exit; } @@ -1064,15 +1088,6 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track) { status_t status = ALREADY_EXISTS; - // here the track could be either new, or restarted - // in both cases "unstop" the track - if (track->isPaused()) { - track->mState = TrackBase::RESUMING; - LOGV("PAUSED => RESUMING (%d) on thread %p", track->name(), this); - } else { - track->mState = TrackBase::ACTIVE; - LOGV("? => ACTIVE (%d) on thread %p", track->name(), this); - } // set retry count for buffer fill track->mRetryCount = kMaxTrackStartupRetries; if (mActiveTracks.indexOf(track) < 0) { @@ -1131,7 +1146,7 @@ void AudioFlinger::PlaybackThread::audioConfigChanged(int event, int param) { break; } Mutex::Autolock _l(mAudioFlinger->mLock); - mAudioFlinger->audioConfigChanged_l(event, this, param2); + mAudioFlinger->audioConfigChanged_l(event, mId, param2); } void AudioFlinger::PlaybackThread::readOutputParameters() @@ -1143,7 +1158,6 @@ void AudioFlinger::PlaybackThread::readOutputParameters() mFrameSize = mOutput->frameSize(); mFrameCount = mOutput->bufferSize() / mFrameSize; - mMinBytesToWrite = (mOutput->latency() * mSampleRate * mFrameSize) / 1000; // FIXME - Current mixer implementation only supports stereo output: Always // Allocate a stereo buffer even if HW output is mono. if (mMixBuffer != NULL) delete mMixBuffer; @@ -1153,8 +1167,8 @@ void AudioFlinger::PlaybackThread::readOutputParameters() // ---------------------------------------------------------------------------- -AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output) - : PlaybackThread(audioFlinger, output), +AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id) + : PlaybackThread(audioFlinger, output, id), mAudioMixer(0) { mType = PlaybackThread::MIXER; @@ -1173,23 +1187,25 @@ AudioFlinger::MixerThread::~MixerThread() bool AudioFlinger::MixerThread::threadLoop() { - uint32_t sleepTime = 0; - uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs(); int16_t* curBuf = mMixBuffer; Vector< sp<Track> > tracksToRemove; - size_t enabledTracks = 0; + uint32_t mixerStatus = MIXER_IDLE; nsecs_t standbyTime = systemTime(); size_t mixBufferSize = mFrameCount * mFrameSize; // FIXME: Relaxed timing because of a certain device that can't meet latency // Should be reduced to 2x after the vendor fixes the driver issue nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 3; nsecs_t lastWarning = 0; + bool longStandbyExit = false; + uint32_t activeSleepTime = activeSleepTimeUs(); + uint32_t idleSleepTime = idleSleepTimeUs(); + uint32_t sleepTime = idleSleepTime; while (!exitPending()) { processConfigEvents(); - enabledTracks = 0; + mixerStatus = MIXER_IDLE; { // scope for mLock Mutex::Autolock _l(mLock); @@ -1199,7 +1215,8 @@ bool AudioFlinger::MixerThread::threadLoop() // FIXME: Relaxed timing because of a certain device that can't meet latency // Should be reduced to 2x after the vendor fixes the driver issue maxPeriod = seconds(mFrameCount) / mSampleRate * 3; - maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs(); + activeSleepTime = activeSleepTimeUs(); + idleSleepTime = idleSleepTimeUs(); } const SortedVector< wp<Track> >& activeTracks = mActiveTracks; @@ -1235,14 +1252,15 @@ bool AudioFlinger::MixerThread::threadLoop() } standbyTime = systemTime() + kStandbyTimeInNsecs; + sleepTime = idleSleepTime; continue; } } - enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove); + mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove); } - if (LIKELY(enabledTracks)) { + if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { // mix buffers... mAudioMixer->process(curBuf); sleepTime = 0; @@ -1251,15 +1269,21 @@ bool AudioFlinger::MixerThread::threadLoop() // If no tracks are ready, sleep once for the duration of an output // buffer size, then write 0s to the output if (sleepTime == 0) { - sleepTime = maxBufferRecoveryInUsecs; - } else if (mBytesWritten != 0) { + if (mixerStatus == MIXER_TRACKS_ENABLED) { + sleepTime = activeSleepTime; + } else { + sleepTime = idleSleepTime; + } + } else if (mBytesWritten != 0 || + (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) { memset (curBuf, 0, mixBufferSize); sleepTime = 0; + LOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start"); } } if (mSuspended) { - sleepTime = maxBufferRecoveryInUsecs; + sleepTime = idleSleepTime; } // sleepTime == 0 means we must write to audio hardware if (sleepTime == 0) { @@ -1269,7 +1293,6 @@ bool AudioFlinger::MixerThread::threadLoop() if (bytesWritten > 0) mBytesWritten += bytesWritten; mNumWrites++; mInWrite = false; - mStandby = false; nsecs_t now = systemTime(); nsecs_t delta = now - mLastWriteTime; if (delta > maxPeriod) { @@ -1279,7 +1302,11 @@ bool AudioFlinger::MixerThread::threadLoop() ns2ms(delta), mNumDelayedWrites, this); lastWarning = now; } + if (mStandby) { + longStandbyExit = true; + } } + mStandby = false; } else { usleep(sleepTime); } @@ -1299,10 +1326,10 @@ bool AudioFlinger::MixerThread::threadLoop() } // prepareTracks_l() must be called with ThreadBase::mLock held -size_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove) +uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove) { - size_t enabledTracks = 0; + uint32_t mixerStatus = MIXER_IDLE; // find out which tracks need to be processed size_t count = activeTracks.size(); for (size_t i=0 ; i<count ; i++) { @@ -1372,7 +1399,7 @@ size_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> // reset retry count track->mRetryCount = kMaxTrackRetries; - enabledTracks++; + mixerStatus = MIXER_TRACKS_READY; } else { //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server); if (track->isStopped()) { @@ -1389,16 +1416,11 @@ size_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> if (--(track->mRetryCount) <= 0) { LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this); tracksToRemove->add(track); + } else if (mixerStatus != MIXER_TRACKS_READY) { + mixerStatus = MIXER_TRACKS_ENABLED; } - // For tracks using static shared memory buffer, make sure that we have - // written enough data to audio hardware before disabling the track - // NOTE: this condition with arrive before track->mRetryCount <= 0 so we - // don't care about code removing track from active list above. - if ((track->mSharedBuffer == 0) || (mBytesWritten >= mMinBytesToWrite)) { - mAudioMixer->disable(AudioMixer::MIXING); - } else { - enabledTracks++; - } + + mAudioMixer->disable(AudioMixer::MIXING); } } } @@ -1416,7 +1438,7 @@ size_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> } } - return enabledTracks; + return mixerStatus; } void AudioFlinger::MixerThread::getTracks( @@ -1503,8 +1525,6 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() AudioParameter param = AudioParameter(keyValuePair); int value; - mNewParameters.removeAt(0); - if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) { reconfig = true; } @@ -1556,6 +1576,9 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED); } } + + mNewParameters.removeAt(0); + mParamStatus = status; mParamCond.signal(); mWaitWorkCV.wait(mLock); @@ -1577,19 +1600,19 @@ status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16> return NO_ERROR; } -uint32_t AudioFlinger::MixerThread::getMaxBufferRecoveryInUsecs() +uint32_t AudioFlinger::MixerThread::activeSleepTimeUs() { - uint32_t time = ((mFrameCount * 1000) / mSampleRate) * 1000; - // Add some margin with regard to scheduling precision - if (time > 10000) { - time -= 10000; - } - return time; + return (uint32_t)(mOutput->latency() * 1000) / 2; +} + +uint32_t AudioFlinger::MixerThread::idleSleepTimeUs() +{ + return (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000; } // ---------------------------------------------------------------------------- -AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output) - : PlaybackThread(audioFlinger, output), +AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id) + : PlaybackThread(audioFlinger, output, id), mLeftVolume (1.0), mRightVolume(1.0) { mType = PlaybackThread::DIRECT; @@ -1602,25 +1625,31 @@ AudioFlinger::DirectOutputThread::~DirectOutputThread() bool AudioFlinger::DirectOutputThread::threadLoop() { - uint32_t sleepTime = 0; - uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs(); + uint32_t mixerStatus = MIXER_IDLE; sp<Track> trackToRemove; sp<Track> activeTrack; nsecs_t standbyTime = systemTime(); int8_t *curBuf; size_t mixBufferSize = mFrameCount*mFrameSize; + uint32_t activeSleepTime = activeSleepTimeUs(); + uint32_t idleSleepTime = idleSleepTimeUs(); + uint32_t sleepTime = idleSleepTime; + while (!exitPending()) { processConfigEvents(); + mixerStatus = MIXER_IDLE; + { // scope for the mLock Mutex::Autolock _l(mLock); if (checkForNewParameters_l()) { mixBufferSize = mFrameCount*mFrameSize; - maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs(); + activeSleepTime = activeSleepTimeUs(); + idleSleepTime = idleSleepTimeUs(); } // put audio hardware into standby after short delay @@ -1654,6 +1683,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } standbyTime = systemTime() + kStandbyTimeInNsecs; + sleepTime = idleSleepTime; continue; } } @@ -1708,6 +1738,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() // reset retry count track->mRetryCount = kMaxTrackRetries; activeTrack = t; + mixerStatus = MIXER_TRACKS_READY; } else { //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server); if (track->isStopped()) { @@ -1723,16 +1754,10 @@ bool AudioFlinger::DirectOutputThread::threadLoop() if (--(track->mRetryCount) <= 0) { LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name()); trackToRemove = track; + } else { + mixerStatus = MIXER_TRACKS_ENABLED; } - - // For tracks using static shared memry buffer, make sure that we have - // written enough data to audio hardware before disabling the track - // NOTE: this condition with arrive before track->mRetryCount <= 0 so we - // don't care about code removing track from active list above. - if ((track->mSharedBuffer != 0) && (mBytesWritten < mMinBytesToWrite)) { - activeTrack = t; - } - } + } } } @@ -1746,7 +1771,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } } - if (activeTrack != 0) { + if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { AudioBufferProvider::Buffer buffer; size_t frameCount = mFrameCount; curBuf = (int8_t *)mMixBuffer; @@ -1767,7 +1792,11 @@ bool AudioFlinger::DirectOutputThread::threadLoop() standbyTime = systemTime() + kStandbyTimeInNsecs; } else { if (sleepTime == 0) { - sleepTime = maxBufferRecoveryInUsecs; + if (mixerStatus == MIXER_TRACKS_ENABLED) { + sleepTime = activeSleepTime; + } else { + sleepTime = idleSleepTime; + } } else if (mBytesWritten != 0 && AudioSystem::isLinearPCM(mFormat)) { memset (mMixBuffer, 0, mFrameCount * mFrameSize); sleepTime = 0; @@ -1775,7 +1804,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } if (mSuspended) { - sleepTime = maxBufferRecoveryInUsecs; + sleepTime = idleSleepTime; } // sleepTime == 0 means we must write to audio hardware if (sleepTime == 0) { @@ -1827,8 +1856,6 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameters_l() AudioParameter param = AudioParameter(keyValuePair); int value; - mNewParameters.removeAt(0); - if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { // do not accept frame count changes if tracks are open as the track buffer // size depends on frame count and correct behavior would not be garantied @@ -1852,6 +1879,9 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameters_l() sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED); } } + + mNewParameters.removeAt(0); + mParamStatus = status; mParamCond.signal(); mWaitWorkCV.wait(mLock); @@ -1859,15 +1889,22 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameters_l() return reconfig; } -uint32_t AudioFlinger::DirectOutputThread::getMaxBufferRecoveryInUsecs() +uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() { uint32_t time; if (AudioSystem::isLinearPCM(mFormat)) { - time = ((mFrameCount * 1000) / mSampleRate) * 1000; - // Add some margin with regard to scheduling precision - if (time > 10000) { - time -= 10000; - } + time = (uint32_t)(mOutput->latency() * 1000) / 2; + } else { + time = 10000; + } + return time; +} + +uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs() +{ + uint32_t time; + if (AudioSystem::isLinearPCM(mFormat)) { + time = (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000; } else { time = 10000; } @@ -1876,8 +1913,8 @@ uint32_t AudioFlinger::DirectOutputThread::getMaxBufferRecoveryInUsecs() // ---------------------------------------------------------------------------- -AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread) - : MixerThread(audioFlinger, mainThread->getOutput()) +AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id) + : MixerThread(audioFlinger, mainThread->getOutput(), id) { mType = PlaybackThread::DUPLICATING; addOutputTrack(mainThread); @@ -1890,28 +1927,30 @@ AudioFlinger::DuplicatingThread::~DuplicatingThread() bool AudioFlinger::DuplicatingThread::threadLoop() { - uint32_t sleepTime = 0; - uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs(); int16_t* curBuf = mMixBuffer; Vector< sp<Track> > tracksToRemove; - size_t enabledTracks = 0; + uint32_t mixerStatus = MIXER_IDLE; nsecs_t standbyTime = systemTime(); size_t mixBufferSize = mFrameCount*mFrameSize; SortedVector< sp<OutputTrack> > outputTracks; uint32_t writeFrames = 0; + uint32_t activeSleepTime = activeSleepTimeUs(); + uint32_t idleSleepTime = idleSleepTimeUs(); + uint32_t sleepTime = idleSleepTime; while (!exitPending()) { processConfigEvents(); - enabledTracks = 0; + mixerStatus = MIXER_IDLE; { // scope for the mLock Mutex::Autolock _l(mLock); if (checkForNewParameters_l()) { mixBufferSize = mFrameCount*mFrameSize; - maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs(); + activeSleepTime = activeSleepTimeUs(); + idleSleepTime = idleSleepTimeUs(); } const SortedVector< wp<Track> >& activeTracks = mActiveTracks; @@ -1951,21 +1990,26 @@ bool AudioFlinger::DuplicatingThread::threadLoop() } standbyTime = systemTime() + kStandbyTimeInNsecs; + sleepTime = idleSleepTime; continue; } } - enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove); + mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove); } - if (LIKELY(enabledTracks)) { + if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { // mix buffers... mAudioMixer->process(curBuf); sleepTime = 0; writeFrames = mFrameCount; } else { if (sleepTime == 0) { - sleepTime = maxBufferRecoveryInUsecs; + if (mixerStatus == MIXER_TRACKS_ENABLED) { + sleepTime = activeSleepTime; + } else { + sleepTime = idleSleepTime; + } } else if (mBytesWritten != 0) { // flush remaining overflow buffers in output tracks for (size_t i = 0; i < outputTracks.size(); i++) { @@ -1979,7 +2023,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop() } if (mSuspended) { - sleepTime = maxBufferRecoveryInUsecs; + sleepTime = idleSleepTime; } // sleepTime == 0 means we must write to audio hardware if (sleepTime == 0) { @@ -2233,8 +2277,10 @@ AudioFlinger::PlaybackThread::Track::~Track() LOGV("PlaybackThread::Track destructor"); sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { - Mutex::Autolock _l(thread->mLock); + thread->mLock.lock(); mState = TERMINATED; + thread->mLock.unlock(); + AudioSystem::releaseOutput(thread->id()); } } @@ -2252,6 +2298,9 @@ void AudioFlinger::PlaybackThread::Track::destroy() { // scope for mLock sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { + if (!isOutputTrack() && (mState == ACTIVE || mState == RESUMING)) { + AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType); + } Mutex::Autolock _l(thread->mLock); PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); playbackThread->destroyTrack_l(this); @@ -2261,7 +2310,7 @@ void AudioFlinger::PlaybackThread::Track::destroy() void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) { - snprintf(buffer, size, " %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n", + snprintf(buffer, size, " %5d %5d %3u %3u %3u %04u %1d %1d %1d %5u %5u %5u %08x %08x\n", mName - AudioMixer::TRACK0, (mClient == NULL) ? getpid() : mClient->pid(), mStreamType, @@ -2333,14 +2382,37 @@ bool AudioFlinger::PlaybackThread::Track::isReady() const { status_t AudioFlinger::PlaybackThread::Track::start() { + status_t status = NO_ERROR; LOGV("start(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid()); sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); - PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); - playbackThread->addTrack_l(this); + int state = mState; + // here the track could be either new, or restarted + // in both cases "unstop" the track + if (mState == PAUSED) { + mState = TrackBase::RESUMING; + LOGV("PAUSED => RESUMING (%d) on thread %p", mName, this); + } else { + mState = TrackBase::ACTIVE; + LOGV("? => ACTIVE (%d) on thread %p", mName, this); + } + + if (!isOutputTrack() && state != ACTIVE && state != RESUMING) { + thread->mLock.unlock(); + status = AudioSystem::startOutput(thread->id(), (AudioSystem::stream_type)mStreamType); + thread->mLock.lock(); + } + if (status == NO_ERROR) { + PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); + playbackThread->addTrack_l(this); + } else { + mState = state; + } + } else { + status = BAD_VALUE; } - return NO_ERROR; + return status; } void AudioFlinger::PlaybackThread::Track::stop() @@ -2349,6 +2421,7 @@ void AudioFlinger::PlaybackThread::Track::stop() sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); + int state = mState; if (mState > STOPPED) { mState = STOPPED; // If the track is not active (PAUSED and buffers full), flush buffers @@ -2358,6 +2431,11 @@ void AudioFlinger::PlaybackThread::Track::stop() } LOGV("(> STOPPED) => STOPPED (%d) on thread %p", mName, playbackThread); } + if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) { + thread->mLock.unlock(); + AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType); + thread->mLock.lock(); + } } } @@ -2370,6 +2448,11 @@ void AudioFlinger::PlaybackThread::Track::pause() if (mState == ACTIVE || mState == RESUMING) { mState = PAUSING; LOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get()); + if (!isOutputTrack()) { + thread->mLock.unlock(); + AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType); + thread->mLock.lock(); + } } } } @@ -2453,6 +2536,10 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( AudioFlinger::RecordThread::RecordTrack::~RecordTrack() { + sp<ThreadBase> thread = mThread.promote(); + if (thread != 0) { + AudioSystem::releaseInput(thread->id()); + } } status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer) @@ -2500,8 +2587,9 @@ status_t AudioFlinger::RecordThread::RecordTrack::start() if (thread != 0) { RecordThread *recordThread = (RecordThread *)thread.get(); return recordThread->start(this); + } else { + return BAD_VALUE; } - return NO_INIT; } void AudioFlinger::RecordThread::RecordTrack::stop() @@ -2517,6 +2605,19 @@ void AudioFlinger::RecordThread::RecordTrack::stop() } } +void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size) +{ + snprintf(buffer, size, " %05d %03u %03u %04u %01d %05u %08x %08x\n", + (mClient == NULL) ? getpid() : mClient->pid(), + mFormat, + mCblk->channels, + mFrameCount, + mState, + mCblk->sampleRate, + mCblk->server, + mCblk->user); +} + // ---------------------------------------------------------------------------- @@ -2925,8 +3026,8 @@ status_t AudioFlinger::RecordHandle::onTransact( // ---------------------------------------------------------------------------- -AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels) : - ThreadBase(audioFlinger), +AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, int id) : + ThreadBase(audioFlinger, id), mInput(input), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0) { mReqChannelCount = AudioSystem::popCount(channels); @@ -2954,6 +3055,7 @@ void AudioFlinger::RecordThread::onFirstRef() run(buffer, PRIORITY_URGENT_AUDIO); } + bool AudioFlinger::RecordThread::threadLoop() { AudioBufferProvider::Buffer buffer; @@ -2999,6 +3101,10 @@ bool AudioFlinger::RecordThread::threadLoop() } if (mActiveTrack != 0) { + if (mActiveTrack->mState != TrackBase::ACTIVE) { + usleep(5000); + continue; + } buffer.frameCount = mFrameCount; if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) { size_t framesOut = buffer.frameCount; @@ -3096,6 +3202,8 @@ bool AudioFlinger::RecordThread::threadLoop() } mActiveTrack.clear(); + mStartStopCond.broadcast(); + LOGV("RecordThread %p exiting", this); return false; } @@ -3103,37 +3211,71 @@ bool AudioFlinger::RecordThread::threadLoop() status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack) { LOGV("RecordThread::start"); - AutoMutex lock(&mLock); - - if (mActiveTrack != 0) { - if (recordTrack != mActiveTrack.get()) return -EBUSY; - - if (mActiveTrack->mState == TrackBase::PAUSING) mActiveTrack->mState = TrackBase::RESUMING; - - return NO_ERROR; - } + sp <ThreadBase> strongMe = this; + status_t status = NO_ERROR; + { + AutoMutex lock(&mLock); + if (mActiveTrack != 0) { + if (recordTrack != mActiveTrack.get()) { + status = -EBUSY; + } else if (mActiveTrack->mState == TrackBase::PAUSING) { + mActiveTrack->mState = TrackBase::RESUMING; + } + return status; + } - mActiveTrack = recordTrack; - mActiveTrack->mState = TrackBase::RESUMING; - // signal thread to start - LOGV("Signal record thread"); - mWaitWorkCV.signal(); - mStartStopCond.wait(mLock); - if (mActiveTrack != 0) { + recordTrack->mState = TrackBase::IDLE; + mActiveTrack = recordTrack; + mLock.unlock(); + status_t status = AudioSystem::startInput(mId); + mLock.lock(); + if (status != NO_ERROR) { + mActiveTrack.clear(); + return status; + } + mActiveTrack->mState = TrackBase::RESUMING; + // signal thread to start + LOGV("Signal record thread"); + mWaitWorkCV.signal(); + // do not wait for mStartStopCond if exiting + if (mExiting) { + mActiveTrack.clear(); + status = INVALID_OPERATION; + goto startError; + } + mStartStopCond.wait(mLock); + if (mActiveTrack == 0) { + LOGV("Record failed to start"); + status = BAD_VALUE; + goto startError; + } LOGV("Record started OK"); - return NO_ERROR; - } else { - LOGV("Record failed to start"); - return BAD_VALUE; + return status; } +startError: + AudioSystem::stopInput(mId); + return status; } void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) { LOGV("RecordThread::stop"); - AutoMutex lock(&mLock); - if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) { - mActiveTrack->mState = TrackBase::PAUSING; - mStartStopCond.wait(mLock); + sp <ThreadBase> strongMe = this; + { + AutoMutex lock(&mLock); + if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) { + mActiveTrack->mState = TrackBase::PAUSING; + // do not wait for mStartStopCond if exiting + if (mExiting) { + return; + } + mStartStopCond.wait(mLock); + // if we have been restarted, recordTrack == mActiveTrack.get() here + if (mActiveTrack == 0 || recordTrack != mActiveTrack.get()) { + mLock.unlock(); + AudioSystem::stopInput(mId); + mLock.lock(); + } + } } } @@ -3144,13 +3286,34 @@ status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args) String8 result; pid_t pid = 0; - if (mActiveTrack != 0 && mActiveTrack->mClient != 0) { - snprintf(buffer, SIZE, "Record client pid: %d\n", mActiveTrack->mClient->pid()); + snprintf(buffer, SIZE, "\nInput thread %p internals\n", this); + result.append(buffer); + + if (mActiveTrack != 0) { + result.append("Active Track:\n"); + result.append(" Clien Fmt Chn Buf S SRate Serv User\n"); + mActiveTrack->dump(buffer, SIZE); + result.append(buffer); + + snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex); result.append(buffer); + snprintf(buffer, SIZE, "In size: %d\n", mInputBytes); + result.append(buffer); + snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != 0)); + result.append(buffer); + snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount); + result.append(buffer); + snprintf(buffer, SIZE, "Out sample rate: %d\n", mReqSampleRate); + result.append(buffer); + + } else { result.append("No record client\n"); } write(fd, result.string(), result.size()); + + dumpBase(fd, args); + return NO_ERROR; } @@ -3206,8 +3369,6 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l() int reqSamplingRate = mReqSampleRate; int reqChannelCount = mReqChannelCount; - mNewParameters.removeAt(0); - if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) { reqSamplingRate = value; reconfig = true; @@ -3249,6 +3410,9 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l() } } } + + mNewParameters.removeAt(0); + mParamStatus = status; mParamCond.signal(); mWaitWorkCV.wait(mLock); @@ -3281,7 +3445,7 @@ void AudioFlinger::RecordThread::audioConfigChanged(int event, int param) { break; } Mutex::Autolock _l(mAudioFlinger->mLock); - mAudioFlinger->audioConfigChanged_l(event, this, param2); + mAudioFlinger->audioConfigChanged_l(event, mId, param2); } void AudioFlinger::RecordThread::readInputParameters() @@ -3369,13 +3533,13 @@ int AudioFlinger::openOutput(uint32_t *pDevices, if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || (format != AudioSystem::PCM_16_BIT) || (channels != AudioSystem::CHANNEL_OUT_STEREO)) { - thread = new DirectOutputThread(this, output); - LOGV("openOutput() created direct output: ID %d thread %p", (mNextThreadId + 1), thread); + thread = new DirectOutputThread(this, output, ++mNextThreadId); + LOGV("openOutput() created direct output: ID %d thread %p", mNextThreadId, thread); } else { - thread = new MixerThread(this, output); - LOGV("openOutput() created mixer output: ID %d thread %p", (mNextThreadId + 1), thread); + thread = new MixerThread(this, output, ++mNextThreadId); + LOGV("openOutput() created mixer output: ID %d thread %p", mNextThreadId, thread); } - mPlaybackThreads.add(++mNextThreadId, thread); + mPlaybackThreads.add(mNextThreadId, thread); if (pSamplingRate) *pSamplingRate = samplingRate; if (pFormat) *pFormat = format; @@ -3398,9 +3562,9 @@ int AudioFlinger::openDuplicateOutput(int output1, int output2) } - DuplicatingThread *thread = new DuplicatingThread(this, thread1); + DuplicatingThread *thread = new DuplicatingThread(this, thread1, ++mNextThreadId); thread->addOutputTrack(thread2); - mPlaybackThreads.add(++mNextThreadId, thread); + mPlaybackThreads.add(mNextThreadId, thread); return mNextThreadId; } @@ -3427,7 +3591,7 @@ status_t AudioFlinger::closeOutput(int output) } } void *param2 = 0; - audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, thread, param2); + audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2); mPlaybackThreads.removeItem(output); } thread->exit(); @@ -3521,8 +3685,8 @@ int AudioFlinger::openInput(uint32_t *pDevices, if (input != 0) { // Start record thread - thread = new RecordThread(this, input, reqSamplingRate, reqChannels); - mRecordThreads.add(++mNextThreadId, thread); + thread = new RecordThread(this, input, reqSamplingRate, reqChannels, ++mNextThreadId); + mRecordThreads.add(mNextThreadId, thread); LOGV("openInput() created record thread: ID %d thread %p", mNextThreadId, thread); if (pSamplingRate) *pSamplingRate = reqSamplingRate; if (pFormat) *pFormat = format; @@ -3548,7 +3712,7 @@ status_t AudioFlinger::closeInput(int input) LOGV("closeInput() %d", input); void *param2 = 0; - audioConfigChanged_l(AudioSystem::INPUT_CLOSED, thread, param2); + audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2); mRecordThreads.removeItem(input); } thread->exit(); diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h index 4bf73ce..5a17294 100644 --- a/libs/audioflinger/AudioFlinger.h +++ b/libs/audioflinger/AudioFlinger.h @@ -133,6 +133,8 @@ public: virtual status_t setStreamOutput(uint32_t stream, int output); + virtual status_t setVoiceVolume(float volume); + // IBinder::DeathRecipient virtual void binderDied(const wp<IBinder>& who); @@ -211,9 +213,11 @@ private: class ThreadBase : public Thread { public: - ThreadBase (const sp<AudioFlinger>& audioFlinger); + ThreadBase (const sp<AudioFlinger>& audioFlinger, int id); virtual ~ThreadBase(); + status_t dumpBase(int fd, const Vector<String16>& args); + // base for record and playback class TrackBase : public AudioBufferProvider, public RefBase { @@ -319,6 +323,7 @@ private: void sendConfigEvent(int event, int param = 0); void sendConfigEvent_l(int event, int param = 0); void processConfigEvents(); + int id() const { return mId;} mutable Mutex mLock; @@ -345,6 +350,8 @@ private: status_t mParamStatus; Vector<ConfigEvent *> mConfigEvents; bool mStandby; + int mId; + bool mExiting; }; // --- PlaybackThread --- @@ -357,6 +364,12 @@ private: DUPLICATING }; + enum mixer_state { + MIXER_IDLE, + MIXER_TRACKS_ENABLED, + MIXER_TRACKS_READY + }; + // playback track class Track : public TrackBase { public: @@ -411,6 +424,10 @@ private: void setPaused() { mState = PAUSED; } void reset(); + bool isOutputTrack() const { + return (mStreamType == AudioSystem::NUM_STREAM_TYPES); + } + // we don't really need a lock for these float mVolume[2]; volatile bool mMute; @@ -463,7 +480,7 @@ private: }; // end of OutputTrack - PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output); + PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id); virtual ~PlaybackThread(); virtual status_t dump(int fd, const Vector<String16>& args); @@ -526,7 +543,8 @@ private: virtual int getTrackName_l() = 0; virtual void deleteTrackName_l(int name) = 0; - virtual uint32_t getMaxBufferRecoveryInUsecs() = 0; + virtual uint32_t activeSleepTimeUs() = 0; + virtual uint32_t idleSleepTimeUs() = 0; private: @@ -558,12 +576,11 @@ private: int mNumWrites; int mNumDelayedWrites; bool mInWrite; - int mMinBytesToWrite; }; class MixerThread : public PlaybackThread { public: - MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output); + MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id); virtual ~MixerThread(); // Thread virtuals @@ -578,10 +595,11 @@ private: virtual status_t dumpInternals(int fd, const Vector<String16>& args); protected: - size_t prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove); + uint32_t prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove); virtual int getTrackName_l(); virtual void deleteTrackName_l(int name); - virtual uint32_t getMaxBufferRecoveryInUsecs(); + virtual uint32_t activeSleepTimeUs(); + virtual uint32_t idleSleepTimeUs(); AudioMixer* mAudioMixer; }; @@ -589,7 +607,7 @@ private: class DirectOutputThread : public PlaybackThread { public: - DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output); + DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id); ~DirectOutputThread(); // Thread virtuals @@ -600,7 +618,8 @@ private: protected: virtual int getTrackName_l(); virtual void deleteTrackName_l(int name); - virtual uint32_t getMaxBufferRecoveryInUsecs(); + virtual uint32_t activeSleepTimeUs(); + virtual uint32_t idleSleepTimeUs(); private: float mLeftVolume; @@ -609,7 +628,7 @@ private: class DuplicatingThread : public MixerThread { public: - DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread); + DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, int id); ~DuplicatingThread(); // Thread virtuals @@ -625,7 +644,7 @@ private: MixerThread *checkMixerThread_l(int output) const; RecordThread *checkRecordThread_l(int input) const; float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; } - void audioConfigChanged_l(int event, const sp<ThreadBase>& thread, void *param2); + void audioConfigChanged_l(int event, int ioHandle, void *param2); friend class AudioBuffer; @@ -676,6 +695,7 @@ private: bool overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; } bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; } + void dump(char* buffer, size_t size); private: friend class AudioFlinger; friend class RecordThread; @@ -692,7 +712,8 @@ private: RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, - uint32_t channels); + uint32_t channels, + int id); ~RecordThread(); virtual bool threadLoop(); diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.cpp b/libs/audioflinger/AudioPolicyManagerGeneric.cpp index 6323859..8cfc204 100644 --- a/libs/audioflinger/AudioPolicyManagerGeneric.cpp +++ b/libs/audioflinger/AudioPolicyManagerGeneric.cpp @@ -459,6 +459,61 @@ status_t AudioPolicyManagerGeneric::getStreamVolumeIndex(AudioSystem::stream_typ return NO_ERROR; } +status_t AudioPolicyManagerGeneric::dump(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); + result.append(buffer); + snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput); + result.append(buffer); + snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); + result.append(buffer); + snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); + result.append(buffer); + snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); + result.append(buffer); + snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode); + result.append(buffer); + snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); + result.append(buffer); + snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); + result.append(buffer); + snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); + result.append(buffer); + write(fd, result.string(), result.size()); + + snprintf(buffer, SIZE, "\nOutputs dump:\n"); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < mOutputs.size(); i++) { + snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); + write(fd, buffer, strlen(buffer)); + mOutputs.valueAt(i)->dump(fd); + } + + snprintf(buffer, SIZE, "\nInputs dump:\n"); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < mInputs.size(); i++) { + snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); + write(fd, buffer, strlen(buffer)); + mInputs.valueAt(i)->dump(fd); + } + + snprintf(buffer, SIZE, "\nStreams dump:\n"); + write(fd, buffer, strlen(buffer)); + snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Mute Count Can be muted\n"); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { + snprintf(buffer, SIZE, " %02d", i); + mStreams[i].dump(buffer + 3, SIZE); + write(fd, buffer, strlen(buffer)); + } + + return NO_ERROR; +} + // ---------------------------------------------------------------------------- // AudioPolicyManagerGeneric // ---------------------------------------------------------------------------- @@ -815,6 +870,35 @@ uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::refCount() return refcount; } +status_t AudioPolicyManagerGeneric::AudioOutputDescriptor::dump(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); + result.append(buffer); + snprintf(buffer, SIZE, " Format: %d\n", mFormat); + result.append(buffer); + snprintf(buffer, SIZE, " Channels: %08x\n", mChannels); + result.append(buffer); + snprintf(buffer, SIZE, " Latency: %d\n", mLatency); + result.append(buffer); + snprintf(buffer, SIZE, " Flags %08x\n", mFlags); + result.append(buffer); + snprintf(buffer, SIZE, " Devices %08x\n", mDevice); + result.append(buffer); + snprintf(buffer, SIZE, " Stream refCount\n"); + result.append(buffer); + for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { + snprintf(buffer, SIZE, " %02d %d\n", i, mRefCount[i]); + result.append(buffer); + } + write(fd, result.string(), result.size()); + + return NO_ERROR; +} + // --- AudioInputDescriptor class implementation AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor() @@ -823,4 +907,39 @@ AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor() { } +status_t AudioPolicyManagerGeneric::AudioInputDescriptor::dump(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); + result.append(buffer); + snprintf(buffer, SIZE, " Format: %d\n", mFormat); + result.append(buffer); + snprintf(buffer, SIZE, " Channels: %08x\n", mChannels); + result.append(buffer); + snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics); + result.append(buffer); + snprintf(buffer, SIZE, " Devices %08x\n", mDevice); + result.append(buffer); + snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount); + result.append(buffer); + write(fd, result.string(), result.size()); + + return NO_ERROR; +} + +// --- StreamDescriptor class implementation + +void AudioPolicyManagerGeneric::StreamDescriptor::dump(char* buffer, size_t size) +{ + snprintf(buffer, size, " %02d %02d %02d %02d %d\n", + mIndexMin, + mIndexMax, + mIndexCur, + mMuteCount, + mCanBeMuted); +} + }; // namespace android diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.h b/libs/audioflinger/AudioPolicyManagerGeneric.h index d904520..4997cdf 100644 --- a/libs/audioflinger/AudioPolicyManagerGeneric.h +++ b/libs/audioflinger/AudioPolicyManagerGeneric.h @@ -76,6 +76,8 @@ public: virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index); virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index); + virtual status_t dump(int fd); + private: enum routing_strategy { @@ -93,6 +95,7 @@ private: public: AudioOutputDescriptor(); + status_t dump(int fd); uint32_t device(); void changeRefCount(AudioSystem::stream_type, int delta); @@ -115,6 +118,8 @@ private: public: AudioInputDescriptor(); + status_t dump(int fd); + uint32_t mSamplingRate; // uint32_t mFormat; // input configuration uint32_t mChannels; // @@ -130,6 +135,8 @@ private: StreamDescriptor() : mIndexMin(0), mIndexMax(1), mIndexCur(1), mMuteCount(0), mCanBeMuted(true) {} + void dump(char* buffer, size_t size); + int mIndexMin; // min volume index int mIndexMax; // max volume index int mIndexCur; // current volume index diff --git a/libs/audioflinger/AudioPolicyService.cpp b/libs/audioflinger/AudioPolicyService.cpp index 5c3cc8e..aa48019 100644 --- a/libs/audioflinger/AudioPolicyService.cpp +++ b/libs/audioflinger/AudioPolicyService.cpp @@ -43,6 +43,12 @@ namespace android { +static const char* kDeadlockedString = "AudioPolicyService may be deadlocked\n"; +static const char* kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n"; + +static const int kDumpLockRetries = 50; +static const int kDumpLockSleep = 20000; + static bool checkPermission() { #ifndef HAVE_ANDROID_OS return true; @@ -335,17 +341,65 @@ void AudioPolicyService::binderDied(const wp<IBinder>& who) { LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid()); } +static bool tryLock(Mutex& mutex) +{ + bool locked = false; + for (int i = 0; i < kDumpLockRetries; ++i) { + if (mutex.tryLock() == NO_ERROR) { + locked = true; + break; + } + usleep(kDumpLockSleep); + } + return locked; +} + +status_t AudioPolicyService::dumpInternals(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager); + result.append(buffer); + snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get()); + result.append(buffer); + snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get()); + result.append(buffer); + + write(fd, result.string(), result.size()); + return NO_ERROR; +} + status_t AudioPolicyService::dump(int fd, const Vector<String16>& args) { if (checkCallingPermission(String16("android.permission.DUMP")) == false) { - dumpPermissionDenial(fd, args); + dumpPermissionDenial(fd); } else { + bool locked = tryLock(mLock); + if (!locked) { + String8 result(kDeadlockedString); + write(fd, result.string(), result.size()); + } + dumpInternals(fd); + if (mAudioCommandThread != NULL) { + mAudioCommandThread->dump(fd); + } + if (mTonePlaybackThread != NULL) { + mTonePlaybackThread->dump(fd); + } + + if (mpPolicyManager) { + mpPolicyManager->dump(fd); + } + + if (locked) mLock.unlock(); } return NO_ERROR; } -status_t AudioPolicyService::dumpPermissionDenial(int fd, const Vector<String16>& args) +status_t AudioPolicyService::dumpPermissionDenial(int fd) { const size_t SIZE = 256; char buffer[SIZE]; @@ -495,6 +549,10 @@ status_t AudioPolicyService::stopTone() return NO_ERROR; } +status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs) +{ + return mAudioCommandThread->voiceVolumeCommand(volume, delayMs); +} // ----------- AudioPolicyService::AudioCommandThread implementation ---------- @@ -534,6 +592,8 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() if (mAudioCommands[0]->mTime <= curTime) { AudioCommand *command = mAudioCommands[0]; mAudioCommands.removeAt(0); + mLastCommand = *command; + switch (command->mCommand) { case START_TONE: { mLock.unlock(); @@ -577,6 +637,16 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() } delete data; }break; + case SET_VOICE_VOLUME: { + VoiceVolumeData *data = (VoiceVolumeData *)command->mParam; + LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume); + command->mStatus = AudioSystem::setVoiceVolume(data->mVolume); + if (command->mWaitStatus) { + command->mCond.signal(); + mWaitWorkCV.wait(mLock); + } + delete data; + }break; default: LOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -595,9 +665,42 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() return false; } +status_t AudioPolicyService::AudioCommandThread::dump(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this); + result.append(buffer); + write(fd, result.string(), result.size()); + + bool locked = tryLock(mLock); + if (!locked) { + String8 result2(kCmdDeadlockedString); + write(fd, result2.string(), result2.size()); + } + + snprintf(buffer, SIZE, "- Commands:\n"); + result = String8(buffer); + result.append(" Command Time Wait pParam\n"); + for (int i = 0; i < (int)mAudioCommands.size(); i++) { + mAudioCommands[i]->dump(buffer, SIZE); + result.append(buffer); + } + result.append(" Last Command\n"); + mLastCommand.dump(buffer, SIZE); + result.append(buffer); + + write(fd, result.string(), result.size()); + + if (locked) mLock.unlock(); + + return NO_ERROR; +} + void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream) { - Mutex::Autolock _l(mLock); AudioCommand *command = new AudioCommand(); command->mCommand = START_TONE; ToneData *data = new ToneData(); @@ -605,6 +708,7 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre data->mStream = stream; command->mParam = (void *)data; command->mWaitStatus = false; + Mutex::Autolock _l(mLock); insertCommand_l(command); LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); mWaitWorkCV.signal(); @@ -612,11 +716,11 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre void AudioPolicyService::AudioCommandThread::stopToneCommand() { - Mutex::Autolock _l(mLock); AudioCommand *command = new AudioCommand(); command->mCommand = STOP_TONE; command->mParam = NULL; command->mWaitStatus = false; + Mutex::Autolock _l(mLock); insertCommand_l(command); LOGV("AudioCommandThread() adding tone stop"); mWaitWorkCV.signal(); @@ -626,7 +730,6 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float { status_t status = NO_ERROR; - Mutex::Autolock _l(mLock); AudioCommand *command = new AudioCommand(); command->mCommand = SET_VOLUME; VolumeData *data = new VolumeData(); @@ -639,6 +742,7 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float } else { command->mWaitStatus = false; } + Mutex::Autolock _l(mLock); insertCommand_l(command, delayMs); LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output); mWaitWorkCV.signal(); @@ -654,7 +758,6 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, { status_t status = NO_ERROR; - Mutex::Autolock _l(mLock); AudioCommand *command = new AudioCommand(); command->mCommand = SET_PARAMETERS; ParametersData *data = new ParametersData(); @@ -666,6 +769,7 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, } else { command->mWaitStatus = false; } + Mutex::Autolock _l(mLock); insertCommand_l(command, delayMs); LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs); mWaitWorkCV.signal(); @@ -677,6 +781,32 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, return status; } +status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs) +{ + status_t status = NO_ERROR; + + AudioCommand *command = new AudioCommand(); + command->mCommand = SET_VOICE_VOLUME; + VoiceVolumeData *data = new VoiceVolumeData(); + data->mVolume = volume; + command->mParam = data; + if (delayMs == 0) { + command->mWaitStatus = true; + } else { + command->mWaitStatus = false; + } + Mutex::Autolock _l(mLock); + insertCommand_l(command, delayMs); + LOGV("AudioCommandThread() adding set voice volume volume %f", volume); + mWaitWorkCV.signal(); + if (command->mWaitStatus) { + command->mCond.wait(mLock); + status = command->mStatus; + mWaitWorkCV.signal(); + } + return status; +} + // insertCommand_l() must be called with mLock held void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs) { @@ -768,4 +898,14 @@ void AudioPolicyService::AudioCommandThread::exit() requestExitAndWait(); } +void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size) +{ + snprintf(buffer, size, " %02d %06d.%03d %01u %p\n", + mCommand, + (int)ns2s(mTime), + (int)ns2ms(mTime)%1000, + mWaitStatus, + mParam); +} + }; // namespace android diff --git a/libs/audioflinger/AudioPolicyService.h b/libs/audioflinger/AudioPolicyService.h index 56a85e1..b9234ec 100644 --- a/libs/audioflinger/AudioPolicyService.h +++ b/libs/audioflinger/AudioPolicyService.h @@ -105,11 +105,14 @@ public: virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys); virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream); virtual status_t stopTone(); + virtual status_t setVoiceVolume(float volume, int delayMs = 0); private: AudioPolicyService(); virtual ~AudioPolicyService(); + status_t dumpInternals(int fd); + // Thread used for tone playback and to send audio config commands to audio flinger // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because startTone() // and stopTone() are normally called with mLock locked and requesting a tone start or stop will cause @@ -125,12 +128,15 @@ private: START_TONE, STOP_TONE, SET_VOLUME, - SET_PARAMETERS + SET_PARAMETERS, + SET_VOICE_VOLUME }; AudioCommandThread (); virtual ~AudioCommandThread(); + status_t dump(int fd); + // Thread virtuals virtual void onFirstRef(); virtual bool threadLoop(); @@ -140,12 +146,19 @@ private: void stopToneCommand(); status_t volumeCommand(int stream, float volume, int output, int delayMs = 0); status_t parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs = 0); + status_t voiceVolumeCommand(float volume, int delayMs = 0); void insertCommand_l(AudioCommand *command, int delayMs = 0); private: // descriptor for requested tone playback event class AudioCommand { + public: + AudioCommand() + : mCommand(-1) {} + + void dump(char* buffer, size_t size); + int mCommand; // START_TONE, STOP_TONE ... nsecs_t mTime; // time stamp Condition mCond; // condition for status return @@ -166,21 +179,27 @@ private: float mVolume; int mIO; }; + class ParametersData { public: int mIO; String8 mKeyValuePairs; }; + class VoiceVolumeData { + public: + float mVolume; + }; Mutex mLock; Condition mWaitWorkCV; Vector <AudioCommand *> mAudioCommands; // list of pending commands ToneGenerator *mpToneGenerator; // the tone generator + AudioCommand mLastCommand; }; // Internal dump utilities. - status_t dumpPermissionDenial(int fd, const Vector<String16>& args); + status_t dumpPermissionDenial(int fd); Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing device diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index c371a23..b2a7db8 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -14,10 +14,13 @@ * limitations under the License. */ +#define LOG_TAG "IPCThreadState" + #include <binder/IPCThreadState.h> #include <binder/Binder.h> #include <binder/BpBinder.h> +#include <cutils/sched_policy.h> #include <utils/Debug.h> #include <utils/Log.h> #include <utils/TextOutput.h> @@ -418,9 +421,26 @@ void IPCThreadState::joinThreadPool(bool isMain) alog << "Processing top-level Command: " << getReturnString(cmd) << endl; } + + result = executeCommand(cmd); } + // After executing the command, ensure that the thread is returned to the + // default cgroup and priority before rejoining the pool. This is a failsafe + // in case the command implementation failed to properly restore the thread's + // scheduling parameters upon completion. + int my_id; +#ifdef HAVE_GETTID + my_id = gettid(); +#else + my_id = getpid(); +#endif + if (!set_sched_policy(my_id, SP_FOREGROUND)) { + // success; reset the priority as well + setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL); + } + // Let this thread exit the thread pool if it is no longer // needed and it is not the main process thread. if(result == TIMED_OUT && !isMain) { diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp index 5df078f..624f7eb 100644 --- a/libs/binder/MemoryHeapBase.cpp +++ b/libs/binder/MemoryHeapBase.cpp @@ -67,7 +67,11 @@ MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags) : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags), mDevice(0), mNeedUnmap(false) { - int fd = open(device, O_RDWR); + int open_flags = O_RDWR; + if (flags & NO_CACHING) + open_flags |= O_SYNC; + + int fd = open(device, open_flags); LOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno)); if (fd >= 0) { const size_t pagesize = getpagesize(); diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp index 3806a42..c660947 100644 --- a/libs/binder/MemoryHeapPmem.cpp +++ b/libs/binder/MemoryHeapPmem.cpp @@ -132,7 +132,7 @@ MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap, char const * const device = pmemHeap->getDevice(); #if HAVE_ANDROID_OS if (device) { - int fd = open(device, O_RDWR); + int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0)); LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno)); if (fd >= 0) { int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID()); diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index d7daf73..2d4e10d 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -41,7 +41,7 @@ #include <sys/mman.h> #include <sys/stat.h> -#define BINDER_VM_SIZE (1*1024*1024) +#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2)) static bool gSingleProcess = false; diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index eb51c22..b3fed58 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -22,9 +22,6 @@ LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES ifeq ($(TARGET_BOARD_PLATFORM), msm7k) LOCAL_CFLAGS += -DDIM_WITH_TEXTURE endif -ifeq ($(TARGET_BOARD_PLATFORM), qsd8k) - LOCAL_CFLAGS += -DDIM_WITH_TEXTURE -endif # need "-lrt" on Linux simulator to pick up clock_gettime ifeq ($(TARGET_SIMULATOR),true) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index f84933e..79c003f 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -246,22 +246,28 @@ void DisplayHardware::init(uint32_t dpy) LOGI("version : %s", glGetString(GL_VERSION)); LOGI("extensions: %s", gl_extensions); - if (strstr(gl_renderer, "PowerVR SGX 530")) { + if (strstr(gl_renderer, "PowerVR SGX 530") || + strstr(gl_renderer, "Adreno")) { LOGD("Assuming uncached graphics buffers."); mFlags &= ~CACHED_BUFFERS; } + if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) { mFlags |= NPOT_EXTENSION; } if (strstr(gl_extensions, "GL_OES_draw_texture")) { mFlags |= DRAW_TEXTURE_EXTENSION; } +#ifdef EGL_ANDROID_image_native_buffer if (strstr( gl_extensions, "GL_OES_EGL_image") && (strstr(egl_extensions, "EGL_KHR_image_base") || strstr(egl_extensions, "EGL_KHR_image")) && strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) { mFlags |= DIRECT_TEXTURE; } +#else +#warning "EGL_ANDROID_image_native_buffer not supported" +#endif // Unbind the context from this thread eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 7fd5434..f5a5a0b 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -134,87 +134,113 @@ void Layer::reloadTexture(const Region& dirty) { Mutex::Autolock _l(mLock); sp<GraphicBuffer> buffer(getFrontBufferLocked()); - if (LIKELY((mFlags & DisplayHardware::DIRECT_TEXTURE) && - (buffer->usage & GRALLOC_USAGE_HW_TEXTURE))) { - int index = mFrontBufferIndex; - if (LIKELY(!mTextures[index].dirty)) { - glBindTexture(GL_TEXTURE_2D, mTextures[index].name); + int index = mFrontBufferIndex; + + // create the new texture name if needed + if (UNLIKELY(mTextures[index].name == -1U)) { + mTextures[index].name = createTexture(); + mTextures[index].width = 0; + mTextures[index].height = 0; + } + +#ifdef EGL_ANDROID_image_native_buffer + if (mFlags & DisplayHardware::DIRECT_TEXTURE) { + if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) { + if (mTextures[index].dirty) { + initializeEglImage(buffer, &mTextures[index]); + } } else { - // we need to recreate the texture - EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); - - // create the new texture name if needed - if (UNLIKELY(mTextures[index].name == -1U)) { - mTextures[index].name = createTexture(); - } else { - glBindTexture(GL_TEXTURE_2D, mTextures[index].name); + if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width || + mHybridBuffer->height != buffer->height)) { + mHybridBuffer.clear(); + mHybridBuffer = new GraphicBuffer( + buffer->width, buffer->height, buffer->format, + GraphicBuffer::USAGE_SW_WRITE_OFTEN | + GraphicBuffer::USAGE_HW_TEXTURE); + initializeEglImage( + mHybridBuffer, &mTextures[0]); } - // free the previous image - if (mTextures[index].image != EGL_NO_IMAGE_KHR) { - eglDestroyImageKHR(dpy, mTextures[index].image); - mTextures[index].image = EGL_NO_IMAGE_KHR; - } - - // construct an EGL_NATIVE_BUFFER_ANDROID - android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); - - // create the new EGLImageKHR - const EGLint attrs[] = { - EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, - EGL_NONE, EGL_NONE - }; - mTextures[index].image = eglCreateImageKHR( - dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, - (EGLClientBuffer)clientBuf, attrs); - - LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR, - "eglCreateImageKHR() failed. err=0x%4x", - eglGetError()); - - if (mTextures[index].image != EGL_NO_IMAGE_KHR) { - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, - (GLeglImageOES)mTextures[index].image); - GLint error = glGetError(); - if (UNLIKELY(error != GL_NO_ERROR)) { - // this failed, for instance, because we don't support - // NPOT. - // FIXME: do something! - LOGD("layer=%p, glEGLImageTargetTexture2DOES(%p) " - "failed err=0x%04x", - this, mTextures[index].image, error); - mFlags &= ~DisplayHardware::DIRECT_TEXTURE; - } else { - // Everything went okay! - mTextures[index].NPOTAdjust = false; - mTextures[index].dirty = false; - mTextures[index].width = clientBuf->width; - mTextures[index].height = clientBuf->height; + GGLSurface t; + status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); + LOGE_IF(res, "error %d (%s) locking buffer %p", + res, strerror(res), buffer.get()); + if (res == NO_ERROR) { + Texture* const texture(&mTextures[0]); + + glBindTexture(GL_TEXTURE_2D, texture->name); + + sp<GraphicBuffer> buf(mHybridBuffer); + void* vaddr; + res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr); + if (res == NO_ERROR) { + int bpp = 0; + switch (t.format) { + case GGL_PIXEL_FORMAT_RGB_565: + case GGL_PIXEL_FORMAT_RGBA_4444: + bpp = 2; + break; + case GGL_PIXEL_FORMAT_RGBA_8888: + case GGL_PIXEL_FORMAT_RGBX_8888: + bpp = 4; + break; + case GGL_PIXEL_FORMAT_YCbCr_422_SP: + case GGL_PIXEL_FORMAT_YCbCr_420_SP: + // just show the Y plane of YUV buffers + bpp = 1; + break; + default: + // oops, we don't handle this format! + LOGE("layer %p, texture=%d, using format %d, which is not " + "supported by the GL", this, texture->name, t.format); + } + if (bpp) { + const Rect bounds(dirty.getBounds()); + size_t src_stride = t.stride; + size_t dst_stride = buf->stride; + if (src_stride == dst_stride && + bounds.width() == t.width && + bounds.height() == t.height) + { + memcpy(vaddr, t.data, t.height * t.stride * bpp); + } else { + GLubyte const * src = t.data + + (bounds.left + bounds.top * src_stride) * bpp; + GLubyte * dst = (GLubyte *)vaddr + + (bounds.left + bounds.top * dst_stride) * bpp; + const size_t length = bounds.width() * bpp; + size_t h = bounds.height(); + src_stride *= bpp; + dst_stride *= bpp; + while (h--) { + memcpy(dst, src, length); + dst += dst_stride; + src += src_stride; + } + } + } + buf->unlock(); } - } + buffer->unlock(); + } } - } else { - for (size_t i=0 ; i<NUM_BUFFERS ; i++) + } else +#endif + { + for (size_t i=0 ; i<NUM_BUFFERS ; i++) { mTextures[i].image = EGL_NO_IMAGE_KHR; - + } GGLSurface t; status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); LOGE_IF(res, "error %d (%s) locking buffer %p", res, strerror(res), buffer.get()); - if (res == NO_ERROR) { - if (UNLIKELY(mTextures[0].name == -1U)) { - mTextures[0].name = createTexture(); - mTextures[0].width = 0; - mTextures[0].height = 0; - } loadTexture(&mTextures[0], dirty, t); buffer->unlock(); } } } - void Layer::onDraw(const Region& clip) const { int index = mFrontBufferIndex; diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 702c51a..1310ecc 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -118,6 +118,7 @@ private: // protected by mLock sp<GraphicBuffer> mBuffers[NUM_BUFFERS]; Texture mTextures[NUM_BUFFERS]; + sp<GraphicBuffer> mHybridBuffer; uint32_t mWidth; uint32_t mHeight; diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index b376e72..8003d22 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -507,7 +507,7 @@ void LayerBase::loadTexture(Texture* texture, // uh? return; } - + glBindTexture(GL_TEXTURE_2D, texture->name); /* @@ -617,6 +617,63 @@ void LayerBase::loadTexture(Texture* texture, } } +status_t LayerBase::initializeEglImage( + const sp<GraphicBuffer>& buffer, Texture* texture) +{ + status_t err = NO_ERROR; + + // we need to recreate the texture + EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); + + // free the previous image + if (texture->image != EGL_NO_IMAGE_KHR) { + eglDestroyImageKHR(dpy, texture->image); + texture->image = EGL_NO_IMAGE_KHR; + } + + // construct an EGL_NATIVE_BUFFER_ANDROID + android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); + + // create the new EGLImageKHR + const EGLint attrs[] = { + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_NONE, EGL_NONE + }; + texture->image = eglCreateImageKHR( + dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + (EGLClientBuffer)clientBuf, attrs); + + LOGE_IF(texture->image == EGL_NO_IMAGE_KHR, + "eglCreateImageKHR() failed. err=0x%4x", + eglGetError()); + + if (texture->image != EGL_NO_IMAGE_KHR) { + glBindTexture(GL_TEXTURE_2D, texture->name); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, + (GLeglImageOES)texture->image); + GLint error = glGetError(); + if (UNLIKELY(error != GL_NO_ERROR)) { + // this failed, for instance, because we don't support NPOT. + // FIXME: do something! + LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) " + "failed err=0x%04x", + this, texture->image, error); + mFlags &= ~DisplayHardware::DIRECT_TEXTURE; + err = INVALID_OPERATION; + } else { + // Everything went okay! + texture->NPOTAdjust = false; + texture->dirty = false; + texture->width = clientBuf->width; + texture->height = clientBuf->height; + } + } else { + err = INVALID_OPERATION; + } + return err; +} + + // --------------------------------------------------------------------------- int32_t LayerBaseClient::sIdentity = 0; diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index efa4f8c..ed07b3f 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -261,6 +261,8 @@ protected: void drawWithOpenGL(const Region& clip, const Texture& texture) const; void loadTexture(Texture* texture, const Region& dirty, const GGLSurface& t) const; + status_t initializeEglImage( + const sp<GraphicBuffer>& buffer, Texture* texture); sp<SurfaceFlinger> mFlinger; diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index 744f2e9..5fd7904 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -40,9 +40,10 @@ const char* const LayerBlur::typeID = "LayerBlur"; LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client, int32_t i) -: LayerBaseClient(flinger, display, client, i), mCacheDirty(true), -mRefreshCache(true), mCacheAge(0), mTextureName(-1U), -mWidthScale(1.0f), mHeightScale(1.0f) + : LayerBaseClient(flinger, display, client, i), mCacheDirty(true), + mRefreshCache(true), mCacheAge(0), mTextureName(-1U), + mWidthScale(1.0f), mHeightScale(1.0f), + mBlurFormat(GGL_PIXEL_FORMAT_RGB_565) { } diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 7e27a02..88ef7e4 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -26,6 +26,8 @@ #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <ui/FramebufferNativeWindow.h> +#include <ui/Rect.h> +#include <ui/Region.h> #include <hardware/copybit.h> @@ -33,26 +35,28 @@ #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" -#include "gralloc_priv.h" // needed for msm / copybit - namespace android { // --------------------------------------------------------------------------- const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20; const char* const LayerBuffer::typeID = "LayerBuffer"; +gralloc_module_t const* LayerBuffer::sGrallocModule = 0; // --------------------------------------------------------------------------- LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client, int32_t i) : LayerBaseClient(flinger, display, client, i), - mNeedsBlending(false) + mNeedsBlending(false), mBlitEngine(0) { } LayerBuffer::~LayerBuffer() { + if (mBlitEngine) { + copybit_close(mBlitEngine); + } } void LayerBuffer::onFirstRef() @@ -60,6 +64,20 @@ void LayerBuffer::onFirstRef() LayerBaseClient::onFirstRef(); mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(), const_cast<LayerBuffer *>(this)); + + hw_module_t const* module = (hw_module_t const*)sGrallocModule; + if (!module) { + // NOTE: technically there is a race here, but it shouldn't + // cause any problem since hw_get_module() always returns + // the same value. + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { + sGrallocModule = (gralloc_module_t const *)module; + } + } + + if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { + copybit_open(module, &mBlitEngine); + } } sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const @@ -100,7 +118,12 @@ uint32_t LayerBuffer::doTransaction(uint32_t flags) sp<Source> source(getSource()); if (source != 0) source->onTransaction(flags); - return LayerBase::doTransaction(flags); + uint32_t res = LayerBase::doTransaction(flags); + // we always want filtering for these surfaces + if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { + mUseLinearFiltering = true; + } + return res; } void LayerBuffer::unlockPageFlip(const Transform& planeTransform, @@ -243,30 +266,36 @@ LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset) : mBufferHeap(buffers) { NativeBuffer& src(mNativeBuffer); - - src.crop.l = 0; - src.crop.t = 0; - src.crop.r = buffers.w; - src.crop.b = buffers.h; - - src.img.w = buffers.hor_stride ?: buffers.w; - src.img.h = buffers.ver_stride ?: buffers.h; - src.img.format = buffers.format; - src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); - - // FIXME: gross hack, we should never access private_handle_t from here, - // but this is needed by msm drivers - private_handle_t* hnd = new private_handle_t( - buffers.heap->heapID(), buffers.heap->getSize(), 0); - hnd->offset = offset; - src.img.handle = hnd; + src.img.handle = 0; + + gralloc_module_t const * module = LayerBuffer::getGrallocModule(); + if (module && module->perform) { + int err = module->perform(module, + GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER, + buffers.heap->heapID(), buffers.heap->getSize(), + offset, buffers.heap->base(), + &src.img.handle); + + if (err == NO_ERROR) { + src.crop.l = 0; + src.crop.t = 0; + src.crop.r = buffers.w; + src.crop.b = buffers.h; + + src.img.w = buffers.hor_stride ?: buffers.w; + src.img.h = buffers.ver_stride ?: buffers.h; + src.img.format = buffers.format; + src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); + } + } } LayerBuffer::Buffer::~Buffer() { NativeBuffer& src(mNativeBuffer); - if (src.img.handle) - delete (private_handle_t*)src.img.handle; + if (src.img.handle) { + native_handle_delete(src.img.handle); + } } // ============================================================================ @@ -335,16 +364,39 @@ LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer, return; } + if (mLayer.mBlitEngine) { + // create our temporary buffer and corresponding EGLImageKHR. + // note that the size of this buffer doesn't really matter, + // the final image will always be drawn with proper aspect ratio. + + int w = buffers.w; + int h = buffers.h; + mTempGraphicBuffer.clear(); + mTempGraphicBuffer = new GraphicBuffer( + w, h, HAL_PIXEL_FORMAT_RGBX_8888, + GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_HW_2D); + + if (mTempGraphicBuffer->initCheck() == NO_ERROR) { + NativeBuffer& dst(mTempBuffer); + dst.img.w = mTempGraphicBuffer->getStride(); + dst.img.h = mTempGraphicBuffer->getHeight(); + dst.img.format = mTempGraphicBuffer->getPixelFormat(); + dst.img.handle = (native_handle_t *)mTempGraphicBuffer->handle; + dst.img.base = 0; + dst.crop.l = 0; + dst.crop.t = 0; + dst.crop.r = mTempGraphicBuffer->getWidth(); + dst.crop.b = mTempGraphicBuffer->getHeight(); + } else { + mTempGraphicBuffer.clear(); + } + } + mBufferHeap = buffers; mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0); mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride; mLayer.forceVisibilityTransaction(); - - hw_module_t const* module; - mBlitEngine = NULL; - if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { - copybit_open(module, &mBlitEngine); - } } LayerBuffer::BufferSource::~BufferSource() @@ -352,8 +404,9 @@ LayerBuffer::BufferSource::~BufferSource() if (mTexture.name != -1U) { glDeleteTextures(1, &mTexture.name); } - if (mBlitEngine) { - copybit_close(mBlitEngine); + if (mTexture.image != EGL_NO_IMAGE_KHR) { + EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay()); + eglDestroyImageKHR(dpy, mTexture.image); } } @@ -421,124 +474,50 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const status_t err = NO_ERROR; NativeBuffer src(ourBuffer->getBuffer()); const Rect transformedBounds(mLayer.getTransformedBounds()); - copybit_device_t* copybit = mBlitEngine; - - if (copybit) { - const int src_width = src.crop.r - src.crop.l; - const int src_height = src.crop.b - src.crop.t; - int W = transformedBounds.width(); - int H = transformedBounds.height(); - if (mLayer.getOrientation() & Transform::ROT_90) { - int t(W); W=H; H=t; - } -#ifdef EGL_ANDROID_get_render_buffer - EGLDisplay dpy = eglGetCurrentDisplay(); - EGLSurface draw = eglGetCurrentSurface(EGL_DRAW); - EGLClientBuffer clientBuf = eglGetRenderBufferANDROID(dpy, draw); - android_native_buffer_t* nb = (android_native_buffer_t*)clientBuf; - if (nb == 0) { - err = BAD_VALUE; - } else { - copybit_image_t dst; - dst.w = nb->width; - dst.h = nb->height; - dst.format = nb->format; - dst.base = NULL; // unused by copybit on msm7k - dst.handle = (native_handle_t *)nb->handle; - - /* With LayerBuffer, it is likely that we'll have to rescale the - * surface, because this is often used for video playback or - * camera-preview. Since we want these operation as fast as possible - * we make sure we can use the 2D H/W even if it doesn't support - * the requested scale factor, in which case we perform the scaling - * in several passes. */ - - const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); - const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); - - float xscale = 1.0f; - if (src_width > W*min) xscale = 1.0f / min; - else if (src_width*mag < W) xscale = mag; - - float yscale = 1.0f; - if (src_height > H*min) yscale = 1.0f / min; - else if (src_height*mag < H) yscale = mag; - - if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { - const int tmp_w = floorf(src_width * xscale); - const int tmp_h = floorf(src_height * yscale); - - if (mTempBitmap==0 || - mTempBitmap->getWidth() < size_t(tmp_w) || - mTempBitmap->getHeight() < size_t(tmp_h)) { - mTempBitmap.clear(); - mTempBitmap = new GraphicBuffer( - tmp_w, tmp_h, src.img.format, - GraphicBuffer::USAGE_HW_2D); - err = mTempBitmap->initCheck(); - } + if (UNLIKELY(mTexture.name == -1LU)) { + mTexture.name = mLayer.createTexture(); + } - if (LIKELY(err == NO_ERROR)) { - NativeBuffer tmp; - tmp.img.w = tmp_w; - tmp.img.h = tmp_h; - tmp.img.format = src.img.format; - tmp.img.handle = (native_handle_t*)mTempBitmap->getNativeBuffer()->handle; - tmp.crop.l = 0; - tmp.crop.t = 0; - tmp.crop.r = tmp.img.w; - tmp.crop.b = tmp.img.h; - - region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); - err = copybit->stretch(copybit, - &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it); - src = tmp; +#if defined(EGL_ANDROID_image_native_buffer) + if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) { + copybit_device_t* copybit = mLayer.mBlitEngine; + if (copybit) { + // create our EGLImageKHR the first time + if (mTexture.image == EGL_NO_IMAGE_KHR) { + err = NO_MEMORY; + if (mTempGraphicBuffer!=0) { + err = mLayer.initializeEglImage( + mTempGraphicBuffer, &mTexture); + // once the EGLImage has been created (whether it fails + // or not) we don't need the graphic buffer reference + // anymore. + mTempGraphicBuffer.clear(); } } - const Rect transformedBounds(mLayer.getTransformedBounds()); - const copybit_rect_t& drect = - reinterpret_cast<const copybit_rect_t&>(transformedBounds); - const State& s(mLayer.drawingState()); - region_iterator it(clip); - - // pick the right orientation for this buffer - int orientation = mLayer.getOrientation(); - if (UNLIKELY(mBufferHeap.transform)) { - Transform rot90; - GraphicPlane::orientationToTransfrom( - ISurfaceComposer::eOrientation90, 0, 0, &rot90); - const Transform& planeTransform(mLayer.graphicPlane(0).transform()); - const Layer::State& s(mLayer.drawingState()); - Transform tr(planeTransform * s.transform * rot90); - orientation = tr.getOrientation(); - } - - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); + if (err == NO_ERROR) { + // NOTE: Assume the buffer is allocated with the proper USAGE flags + const NativeBuffer& dst(mTempBuffer); + region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b))); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); + err = copybit->stretch(copybit, &dst.img, &src.img, + &dst.crop, &src.crop, &clip); - err = copybit->stretch(copybit, - &dst, &src.img, &drect, &src.crop, &it); - if (err != NO_ERROR) { - LOGE("copybit failed (%s)", strerror(err)); } + } else { + err = INVALID_OPERATION; } } #endif - - if (!copybit || err) - { - // OpenGL fall-back - if (UNLIKELY(mTexture.name == -1LU)) { - mTexture.name = mLayer.createTexture(); - } - GLuint w = 0; - GLuint h = 0; + else { + err = INVALID_OPERATION; + } + + if (err != NO_ERROR) { + // slower fallback GGLSurface t; t.version = sizeof(GGLSurface); t.width = src.crop.r; @@ -549,11 +528,11 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const t.data = (GGLubyte*)src.img.base; const Region dirty(Rect(t.width, t.height)); mLayer.loadTexture(&mTexture, dirty, t); - mTexture.transform = mBufferHeap.transform; - mLayer.drawWithOpenGL(clip, mTexture); } -} + mTexture.transform = mBufferHeap.transform; + mLayer.drawWithOpenGL(clip, mTexture); +} // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 5eb472c..1abb103 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -91,6 +91,11 @@ private: copybit_rect_t crop; }; + static gralloc_module_t const* sGrallocModule; + static gralloc_module_t const* getGrallocModule() { + return sGrallocModule; + } + class Buffer : public LightRefBase<Buffer> { public: Buffer(const ISurface::BufferHeap& buffers, ssize_t offset); @@ -130,9 +135,9 @@ private: status_t mStatus; ISurface::BufferHeap mBufferHeap; size_t mBufferSize; - mutable sp<GraphicBuffer> mTempBitmap; mutable LayerBase::Texture mTexture; - copybit_device_t* mBlitEngine; + NativeBuffer mTempBuffer; + mutable sp<GraphicBuffer> mTempGraphicBuffer; }; class OverlaySource : public Source { @@ -201,6 +206,7 @@ private: sp<Surface> mSurface; bool mInvalidate; bool mNeedsBlending; + copybit_device_t* mBlitEngine; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index 538dc77..fd61e30 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -55,8 +55,8 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) sHeight = h; sUseTexture = false; -#ifdef DIM_WITH_TEXTURE - +#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer) + #warning "using a texture to implement LayerDim" /* On some h/w like msm7K, it is faster to use a texture because the @@ -69,7 +69,6 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) uint32_t flags = hw.getFlags(); if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) { - // TODO: api to pass the usage flags sp<GraphicBuffer> buffer = new GraphicBuffer(w, h, PIXEL_FORMAT_RGB_565, GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE); @@ -123,7 +122,7 @@ void LayerDim::onDraw(const Region& clip) const glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glColor4x(0, 0, 0, alpha); -#ifdef DIM_WITH_TEXTURE +#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer) if (sUseTexture) { glBindTexture(GL_TEXTURE_2D, sTexId); glEnable(GL_TEXTURE_2D); diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 6698e00..f9bfe6c 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -246,8 +246,10 @@ private: virtual status_t readyToRun(); virtual void onFirstRef(); +public: // hack to work around gcc 4.0.3 bug const GraphicPlane& graphicPlane(int dpy) const; GraphicPlane& graphicPlane(int dpy); +private: void waitForEvent(); public: // hack to work around gcc 4.0.3 bug diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 1cf20d7..6a5c8a9 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -37,7 +37,7 @@ namespace android { // =========================================================================== GraphicBuffer::GraphicBuffer() - : BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()), + : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) { width = @@ -50,7 +50,7 @@ GraphicBuffer::GraphicBuffer() GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, PixelFormat reqFormat, uint32_t reqUsage) - : BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()), + : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) { width = @@ -62,8 +62,23 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, mInitCheck = initSize(w, h, reqFormat, reqUsage); } +GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, + PixelFormat inFormat, uint32_t inUsage, + uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) + : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), + mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) +{ + width = w; + height = h; + stride = inStride; + format = inFormat; + usage = inUsage; + handle = inHandle; +} + GraphicBuffer::GraphicBuffer(const Parcel& data) - : BASE(), mOwner(true), mBufferMapper(GraphicBufferMapper::get()), + : BASE(), mOwner(ownHandle), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) { // we own the handle in this case @@ -83,10 +98,10 @@ GraphicBuffer::GraphicBuffer(const Parcel& data) GraphicBuffer::~GraphicBuffer() { if (handle) { - if (mOwner) { + if (mOwner == ownHandle) { native_handle_close(handle); native_handle_delete(const_cast<native_handle*>(handle)); - } else { + } else if (mOwner == ownData) { GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); } @@ -106,6 +121,9 @@ android_native_buffer_t* GraphicBuffer::getNativeBuffer() const status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f, uint32_t reqUsage) { + if (mOwner != ownData) + return INVALID_OPERATION; + if (handle) { GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); @@ -208,6 +226,14 @@ int GraphicBuffer::getIndex() const { return mIndex; } +void GraphicBuffer::setVerticalStride(uint32_t vstride) { + mVStride = vstride; +} + +uint32_t GraphicBuffer::getVerticalStride() const { + return mVStride; +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index f51ca7a..24ae27f 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -152,96 +152,85 @@ bool SurfaceControl::isSameSurface( status_t SurfaceControl::setLayer(int32_t layer) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setLayer(mToken, layer); } status_t SurfaceControl::setPosition(int32_t x, int32_t y) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setPosition(mToken, x, y); } status_t SurfaceControl::setSize(uint32_t w, uint32_t h) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setSize(mToken, w, h); } status_t SurfaceControl::hide() { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->hide(mToken); } status_t SurfaceControl::show(int32_t layer) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->show(mToken, layer); } status_t SurfaceControl::freeze() { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->freeze(mToken); } status_t SurfaceControl::unfreeze() { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->unfreeze(mToken); } status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setFlags(mToken, flags, mask); } status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setTransparentRegionHint(mToken, transparent); } status_t SurfaceControl::setAlpha(float alpha) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setAlpha(mToken, alpha); } status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); } status_t SurfaceControl::setFreezeTint(uint32_t tint) { const sp<SurfaceComposerClient>& client(mClient); - if (client == 0) return NO_INIT; - status_t err = validate(client->mControl); + status_t err = validate(); if (err < 0) return err; return client->setFreezeTint(mToken, tint); } -status_t SurfaceControl::validate(SharedClient const* cblk) const +status_t SurfaceControl::validate() const { if (mToken<0 || mClient==0) { LOGE("invalid token (%d, identity=%u) or client (%p)", mToken, mIdentity, mClient.get()); return NO_INIT; } + SharedClient const* cblk = mClient->mControl; if (cblk == 0) { LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); return NO_INIT; @@ -394,7 +383,7 @@ bool Surface::isValid() { return mToken>=0 && mClient!=0; } -status_t Surface::validate(SharedClient const* cblk) const +status_t Surface::validate() const { sp<SurfaceComposerClient> client(getClient()); if (mToken<0 || mClient==0) { @@ -402,6 +391,7 @@ status_t Surface::validate(SharedClient const* cblk) const mToken, mIdentity, client.get()); return NO_INIT; } + SharedClient const* cblk = mClient->mControl; if (cblk == 0) { LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); return NO_INIT; @@ -488,7 +478,7 @@ status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) { int Surface::dequeueBuffer(android_native_buffer_t** buffer) { sp<SurfaceComposerClient> client(getClient()); - status_t err = validate(client->mControl); + status_t err = validate(); if (err != NO_ERROR) return err; @@ -533,7 +523,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) int Surface::lockBuffer(android_native_buffer_t* buffer) { sp<SurfaceComposerClient> client(getClient()); - status_t err = validate(client->mControl); + status_t err = validate(); if (err != NO_ERROR) return err; @@ -546,7 +536,7 @@ int Surface::lockBuffer(android_native_buffer_t* buffer) int Surface::queueBuffer(android_native_buffer_t* buffer) { sp<SurfaceComposerClient> client(getClient()); - status_t err = validate(client->mControl); + status_t err = validate(); if (err != NO_ERROR) return err; diff --git a/libs/ui/tests/region.cpp b/libs/ui/tests/region.cpp index 0deb2ba..ef15de9 100644 --- a/libs/ui/tests/region.cpp +++ b/libs/ui/tests/region.cpp @@ -25,9 +25,16 @@ using namespace android; int main() { + Region empty; Region reg0( Rect( 0, 0, 100, 100 ) ); Region reg1 = reg0; Region reg2, reg3; + + Region reg4 = empty | reg1; + Region reg5 = reg1 | empty; + + reg4.dump("reg4"); + reg5.dump("reg5"); reg0.dump("reg0"); reg1.dump("reg1"); diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 872b2bc..450af8d 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -42,6 +42,7 @@ #define TABLE_GETENTRY(x) //x #define TABLE_SUPER_NOISY(x) //x #define LOAD_TABLE_NOISY(x) //x +#define TABLE_THEME(x) //x namespace android { @@ -1447,18 +1448,23 @@ ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue, const uint32_t t = Res_GETTYPE(resID); const uint32_t e = Res_GETENTRY(resID); - TABLE_NOISY(LOGV("Looking up attr 0x%08x in theme %p", resID, this)); + TABLE_THEME(LOGI("Looking up attr 0x%08x in theme %p", resID, this)); if (p >= 0) { const package_info* const pi = mPackages[p]; + TABLE_THEME(LOGI("Found package: %p", pi)); if (pi != NULL) { + TABLE_THEME(LOGI("Desired type index is %ld in avail %d", t, pi->numTypes)); if (t < pi->numTypes) { const type_info& ti = pi->types[t]; + TABLE_THEME(LOGI("Desired entry index is %ld in avail %d", e, ti.numEntries)); if (e < ti.numEntries) { const theme_entry& te = ti.entries[e]; - if (outTypeSpecFlags != NULL) { - *outTypeSpecFlags |= te.typeSpecFlags; - } + if (outTypeSpecFlags != NULL) { + *outTypeSpecFlags |= te.typeSpecFlags; + } + TABLE_THEME(LOGI("Theme value: type=0x%x, data=0x%08x", + te.value.dataType, te.value.data)); const uint8_t type = te.value.dataType; if (type == Res_value::TYPE_ATTRIBUTE) { if (cnt > 0) { @@ -1492,6 +1498,8 @@ ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue, if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) { uint32_t newTypeSpecFlags; blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags); + TABLE_THEME(LOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n", + (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data)); if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags; //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType); if (blockIndex < 0) { @@ -1911,8 +1919,8 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, uint32_t newFlags = 0; const ssize_t newIndex = getResource(value->data, value, true, &newFlags, outConfig); - //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n", - // (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data); + TABLE_THEME(LOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n", + (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data)); //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex); if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags; if (newIndex < 0) { diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 2522656..9837845 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -25,6 +25,13 @@ LOCAL_SRC_FILES:= \ primitives.cpp.arm \ vertex.cpp.arm +LOCAL_CFLAGS += -DLOG_TAG=\"libagl\" +LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES +LOCAL_CFLAGS += -fvisibility=hidden + +LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger +LOCAL_LDLIBS := -lpthread -ldl + ifeq ($(TARGET_ARCH),arm) LOCAL_SRC_FILES += fixed_asm.S iterators.S LOCAL_CFLAGS += -fstrict-aliasing @@ -38,15 +45,9 @@ endif ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1) LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS LOCAL_SRC_FILES += copybit.cpp + LOCAL_SHARED_LIBRARIES += libui endif -LOCAL_CFLAGS += -DLOG_TAG=\"libagl\" -LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES - -LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger -LOCAL_CFLAGS += -fvisibility=hidden - -LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl LOCAL_MODULE:= libGLES_android diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp index 4878722..71825c5 100644 --- a/opengl/libagl/array.cpp +++ b/opengl/libagl/array.cpp @@ -1548,24 +1548,36 @@ void glDeleteBuffers(GLsizei n, const GLuint* buffers) GLuint name = buffers[i]; if (name) { // unbind bound deleted buffers... - if (c->arrays.element_array_buffer->name == name) { - c->arrays.element_array_buffer = 0; + if (c->arrays.element_array_buffer) { + if (c->arrays.element_array_buffer->name == name) { + c->arrays.element_array_buffer = 0; + } } - if (c->arrays.array_buffer->name == name) { - c->arrays.array_buffer = 0; + if (c->arrays.array_buffer) { + if (c->arrays.array_buffer->name == name) { + c->arrays.array_buffer = 0; + } } - if (c->arrays.vertex.bo->name == name) { - c->arrays.vertex.bo = 0; + if (c->arrays.vertex.bo) { + if (c->arrays.vertex.bo->name == name) { + c->arrays.vertex.bo = 0; + } } - if (c->arrays.normal.bo->name == name) { - c->arrays.normal.bo = 0; + if (c->arrays.normal.bo) { + if (c->arrays.normal.bo->name == name) { + c->arrays.normal.bo = 0; + } } - if (c->arrays.color.bo->name == name) { - c->arrays.color.bo = 0; + if (c->arrays.color.bo) { + if (c->arrays.color.bo->name == name) { + c->arrays.color.bo = 0; + } } for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) { - if (c->arrays.texture[t].bo->name == name) { - c->arrays.texture[t].bo = 0; + if (c->arrays.texture[t].bo) { + if (c->arrays.texture[t].bo->name == name) { + c->arrays.texture[t].bo = 0; + } } } } diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 867459d..a68750e 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -33,6 +33,10 @@ #include <hardware/copybit.h> #include <private/ui/android_natives_priv.h> +#include <ui/GraphicBuffer.h> +#include <ui/Region.h> +#include <ui/Rect.h> + #define DEBUG_COPYBIT true @@ -41,13 +45,25 @@ namespace android { static void textureToCopyBitImage( - const GGLSurface* surface, buffer_handle_t buffer, copybit_image_t* img) + const GGLSurface* surface, int32_t opFormat, + android_native_buffer_t* buffer, copybit_image_t* img) { + uint32_t vstride = 0; + if (opFormat == COPYBIT_FORMAT_YCbCr_422_SP || + opFormat == COPYBIT_FORMAT_YCbCr_420_SP) { + // NOTE: this static_cast is really not safe b/c we can't know for + // sure the buffer passed is of the right type. + // However, since we do this only for YUV formats, we should be safe + // since only SurfaceFlinger makes use of them. + GraphicBuffer* graphicBuffer = static_cast<GraphicBuffer*>(buffer); + vstride = graphicBuffer->getVerticalStride(); + } + img->w = surface->stride; - img->h = surface->height; - img->format = surface->format; + img->h = vstride ? vstride : surface->height; + img->format = opFormat; img->base = surface->data; - img->handle = (native_handle_t *)buffer; + img->handle = (native_handle_t *)buffer->handle; } struct clipRectRegion : public copybit_region_t { @@ -69,6 +85,7 @@ private: static int iterate_done(copybit_region_t const *, copybit_rect_t*) { return 0; } +public: copybit_rect_t r; }; @@ -149,6 +166,8 @@ static bool copybit(GLint x, GLint y, int transform, ogles_context_t* c) { + status_t err = NO_ERROR; + // We assume checkContext has already been called and has already // returned true. @@ -174,16 +193,6 @@ static bool copybit(GLint x, GLint y, dtdy /= screen_h; } dtdy = -dtdy; // see equation of dtdy above - if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale - || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) { - // The requested scale is out of the range the hardware - // can support. - LOGD_IF(DEBUG_COPYBIT, - "scale out of range dsdx=%08x (Wcr=%d / w=%d), " - "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", - dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr); - return false; - } // copybit doesn't say anything about filtering, so we can't // discriminate. On msm7k, copybit will always filter. @@ -205,41 +214,16 @@ static bool copybit(GLint x, GLint y, const uint32_t enables = c->rasterizer.state.enables; int planeAlpha = 255; + bool alphaPlaneWorkaround = false; static const int tmu = 0; texture_t& tev(c->rasterizer.state.texture[tmu]); - bool srcTextureHasAlpha = hasAlpha(textureObject->surface.format); + int32_t opFormat = textureObject->surface.format; + const bool srcTextureHasAlpha = hasAlpha(opFormat); if (!srcTextureHasAlpha) { planeAlpha = fixedToByte(c->currentColorClamped.a); } - switch (tev.env) { - case GGL_REPLACE: - break; - case GGL_MODULATE: - if (! (c->currentColorClamped.r == FIXED_ONE && - c->currentColorClamped.g == FIXED_ONE && - c->currentColorClamped.b == FIXED_ONE)) { - LOGD_IF(DEBUG_COPYBIT, - "MODULATE and non white color (%08x, %08x, %08x)", - c->currentColorClamped.r, - c->currentColorClamped.g, - c->currentColorClamped.b); - return false; - } - if (srcTextureHasAlpha && c->currentColorClamped.a < FIXED_ONE) { - LOGD_IF(DEBUG_COPYBIT, - "MODULATE and texture w/alpha and alpha=%08x)", - c->currentColorClamped.a); - return false; - } - break; - - default: - // Incompatible texture environment. - LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment"); - return false; - } - + const bool cbHasAlpha = hasAlpha(cbSurface.format); bool blending = false; if ((enables & GGL_ENABLE_BLENDING) && !(c->rasterizer.state.blend.src == GL_ONE @@ -262,41 +246,228 @@ static bool copybit(GLint x, GLint y, } blending = true; } else { - // No blending is OK if we are not using alpha. - if (srcTextureHasAlpha || planeAlpha != 255) { - // Incompatible alpha - LOGD_IF(DEBUG_COPYBIT, "incompatible alpha"); - return false; + if (cbHasAlpha) { + // NOTE: the result will be slightly wrong in this case because + // the destination alpha channel will be set to 1.0 instead of + // the iterated alpha value. *shrug*. + } + // disable plane blending and src blending for supported formats + planeAlpha = 255; + if (opFormat == COPYBIT_FORMAT_RGBA_8888) { + opFormat = COPYBIT_FORMAT_RGBX_8888; + } else { + if (srcTextureHasAlpha) { + LOGD_IF(DEBUG_COPYBIT, "texture format requires blending"); + return false; + } } } - if (srcTextureHasAlpha && planeAlpha != 255) { - // Can't do two types of alpha at once. - LOGD_IF(DEBUG_COPYBIT, "src alpha and plane alpha"); + switch (tev.env) { + case GGL_REPLACE: + break; + case GGL_MODULATE: + // only cases allowed is: + // RGB source, color={1,1,1,a} -> can be done with GL_REPLACE + // RGBA source, color={1,1,1,1} -> can be done with GL_REPLACE + if (blending) { + if (c->currentColorClamped.r == c->currentColorClamped.a && + c->currentColorClamped.g == c->currentColorClamped.a && + c->currentColorClamped.b == c->currentColorClamped.a) { + // TODO: RGBA source, color={1,1,1,a} / regular-blending + // is equivalent + alphaPlaneWorkaround = true; + break; + } + } + LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE"); + return false; + default: + // Incompatible texture environment. + LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment"); return false; } - // LOGW("calling copybits"); - copybit_device_t* copybit = c->copybits.blitEngine; + copybit_image_t src; + textureToCopyBitImage(&textureObject->surface, opFormat, + textureObject->buffer, &src); + copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; + + /* + * Below we perform extra passes needed to emulate things the h/w + * cannot do. + */ + + const GLfixed minScaleInv = gglDivQ(0x10000, c->copybits.minScale, 16); + const GLfixed maxScaleInv = gglDivQ(0x10000, c->copybits.maxScale, 16); + + sp<GraphicBuffer> tempBitmap; + + if (dsdx < maxScaleInv || dsdx > minScaleInv || + dtdy < maxScaleInv || dtdy > minScaleInv) + { + // The requested scale is out of the range the hardware + // can support. + LOGD_IF(DEBUG_COPYBIT, + "scale out of range dsdx=%08x (Wcr=%d / w=%d), " + "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", + dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr); + + int32_t xscale=0x10000, yscale=0x10000; + if (dsdx > minScaleInv) xscale = c->copybits.minScale; + else if (dsdx < maxScaleInv) xscale = c->copybits.maxScale; + if (dtdy > minScaleInv) yscale = c->copybits.minScale; + else if (dtdy < maxScaleInv) yscale = c->copybits.maxScale; + dsdx = gglMulx(dsdx, xscale); + dtdy = gglMulx(dtdy, yscale); + + /* we handle only one step of resizing below. Handling an arbitrary + * number is relatively easy (replace "if" above by "while"), but requires + * two intermediate buffers and so far we never had the need. + */ + + if (dsdx < maxScaleInv || dsdx > minScaleInv || + dtdy < maxScaleInv || dtdy > minScaleInv) { + LOGD_IF(DEBUG_COPYBIT, + "scale out of range dsdx=%08x (Wcr=%d / w=%d), " + "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", + dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr); + return false; + } + + const int tmp_w = gglMulx(srect.r - srect.l, xscale, 16); + const int tmp_h = gglMulx(srect.b - srect.t, yscale, 16); + + LOGD_IF(DEBUG_COPYBIT, + "xscale=%08x, yscale=%08x, dsdx=%08x, dtdy=%08x, tmp_w=%d, tmp_h=%d", + xscale, yscale, dsdx, dtdy, tmp_w, tmp_h); + + tempBitmap = new GraphicBuffer( + tmp_w, tmp_h, src.format, + GraphicBuffer::USAGE_HW_2D); + + err = tempBitmap->initCheck(); + if (err == NO_ERROR) { + copybit_image_t tmp_dst; + copybit_rect_t tmp_rect; + tmp_dst.w = tmp_w; + tmp_dst.h = tmp_h; + tmp_dst.format = tempBitmap->format; + tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle; + tmp_rect.l = 0; + tmp_rect.t = 0; + tmp_rect.r = tmp_dst.w; + tmp_rect.b = tmp_dst.h; + region_iterator tmp_it(Region(Rect(tmp_rect.r, tmp_rect.b))); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); + err = copybit->stretch(copybit, + &tmp_dst, &src, &tmp_rect, &srect, &tmp_it); + src = tmp_dst; + srect = tmp_rect; + } + } copybit_image_t dst; - buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer; - textureToCopyBitImage(&cbSurface, target_hnd, &dst); + textureToCopyBitImage(&cbSurface, cbSurface.format, + c->copybits.drawSurfaceBuffer, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; - copybit_image_t src; - buffer_handle_t source_hnd = textureObject->buffer->handle; - textureToCopyBitImage(&textureObject->surface, source_hnd, &src); - copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, - (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); + /* and now the alpha-plane hack. This handles the "Fade" case of a + * texture with an alpha channel. + */ + if (alphaPlaneWorkaround) { + sp<GraphicBuffer> tempCb = new GraphicBuffer( + w, h, COPYBIT_FORMAT_RGB_565, + GraphicBuffer::USAGE_HW_2D); + + err = tempCb->initCheck(); + + copybit_image_t tmpCbImg; + copybit_rect_t tmpCbRect; + copybit_rect_t tmpdrect = drect; + tmpCbImg.w = w; + tmpCbImg.h = h; + tmpCbImg.format = tempCb->format; + tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle; + tmpCbRect.l = 0; + tmpCbRect.t = 0; + + if (drect.l < 0) { + tmpCbRect.l = -tmpdrect.l; + tmpdrect.l = 0; + } + if (drect.t < 0) { + tmpCbRect.t = -tmpdrect.t; + tmpdrect.t = 0; + } + if (drect.l + tmpCbImg.w > dst.w) { + tmpCbImg.w = dst.w - drect.l; + tmpdrect.r = dst.w; + } + if (drect.t + tmpCbImg.h > dst.h) { + tmpCbImg.h = dst.h - drect.t; + tmpdrect.b = dst.h; + } - clipRectRegion it(c); - status_t err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + tmpCbRect.r = tmpCbImg.w; + tmpCbRect.b = tmpCbImg.h; + + if (!err) { + // first make a copy of the destination buffer + region_iterator tmp_it(Region(Rect(w, h))); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); + err = copybit->stretch(copybit, + &tmpCbImg, &dst, &tmpCbRect, &tmpdrect, &tmp_it); + } + if (!err) { + // then proceed as usual, but without the alpha plane + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, + (enables & GGL_ENABLE_DITHER) ? + COPYBIT_ENABLE : COPYBIT_DISABLE); + clipRectRegion it(c); + err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + } + if (!err) { + // finally copy back the destination on top with 1-alphaplane + int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a); + clipRectRegion it(c); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); + err = copybit->stretch(copybit, + &dst, &tmpCbImg, &tmpdrect, &tmpCbRect, &it); + } + } else { + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, + (enables & GGL_ENABLE_DITHER) ? + COPYBIT_ENABLE : COPYBIT_DISABLE); + clipRectRegion it(c); + + LOGD_IF(0, + "dst={%d, %d, %d, %p, %p}, " + "src={%d, %d, %d, %p, %p}, " + "drect={%d,%d,%d,%d}, " + "srect={%d,%d,%d,%d}, " + "it={%d,%d,%d,%d}, " , + dst.w, dst.h, dst.format, dst.base, dst.handle, + src.w, src.h, src.format, src.base, src.handle, + drect.l, drect.t, drect.r, drect.b, + srect.l, srect.t, srect.r, srect.b, + it.r.l, it.r.t, it.r.r, it.r.b + ); + + err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + } if (err != NO_ERROR) { c->textures.tmu[0].texture->try_copybit = false; } diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 37628b7..781b8c3 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -40,6 +40,7 @@ #include <pixelflinger/pixelflinger.h> #include <private/ui/android_natives_priv.h> +#include <private/ui/sw_gralloc_handle.h> #include <hardware/copybit.h> @@ -449,15 +450,26 @@ void egl_window_surface_v2_t::disconnect() status_t egl_window_surface_v2_t::lock( android_native_buffer_t* buf, int usage, void** vaddr) { - int err = module->lock(module, buf->handle, - usage, 0, 0, buf->width, buf->height, vaddr); + int err; + if (sw_gralloc_handle_t::validate(buf->handle) < 0) { + err = module->lock(module, buf->handle, + usage, 0, 0, buf->width, buf->height, vaddr); + } else { + sw_gralloc_handle_t const* hnd = + reinterpret_cast<sw_gralloc_handle_t const*>(buf->handle); + *vaddr = (void*)hnd->base; + err = NO_ERROR; + } return err; } status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) { if (!buf) return BAD_VALUE; - int err = module->unlock(module, buf->handle); + int err = NO_ERROR; + if (sw_gralloc_handle_t::validate(buf->handle) < 0) { + err = module->unlock(module, buf->handle); + } return err; } @@ -623,6 +635,7 @@ static bool supportedCopybitsDestinationFormat(int format) { switch (format) { case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_RGBA_4444: case HAL_PIXEL_FORMAT_RGBA_5551: case HAL_PIXEL_FORMAT_BGRA_8888: @@ -651,7 +664,7 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) if (supportedCopybitsDestinationFormat(buffer.format)) { buffer_handle_t handle = this->buffer->handle; if (handle != NULL) { - gl->copybits.drawSurfaceBuffer = handle; + gl->copybits.drawSurfaceBuffer = this->buffer; } } } @@ -792,6 +805,7 @@ egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, case GGL_PIXEL_FORMAT_A_8: size *= 1; break; case GGL_PIXEL_FORMAT_RGB_565: size *= 2; break; case GGL_PIXEL_FORMAT_RGBA_8888: size *= 4; break; + case GGL_PIXEL_FORMAT_RGBX_8888: size *= 4; break; default: LOGE("incompatible pixel format for pbuffer (format=%d)", f); pbuffer.data = 0; @@ -862,7 +876,7 @@ struct config_management_t { #define VERSION_MAJOR 1 #define VERSION_MINOR 2 static char const * const gVendorString = "Google Inc."; -static char const * const gVersionString = "1.2 Android Driver"; +static char const * const gVersionString = "1.2 Android Driver 1.1.0"; static char const * const gClientApiString = "OpenGL ES"; static char const * const gExtensionsString = "EGL_KHR_image_base " @@ -953,12 +967,17 @@ static config_pair_t const config_base_attribute_list[] = { { EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE }, { EGL_MIN_SWAP_INTERVAL, 1 }, { EGL_MAX_SWAP_INTERVAL, 1 }, + { EGL_LUMINANCE_SIZE, 0 }, + { EGL_ALPHA_MASK_SIZE, 0 }, + { EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER }, { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT }, + { EGL_CONFORMANT, 0 } }; // These configs can override the base attribute list // NOTE: when adding a config here, don't forget to update eglCreate*Surface() +// 565 configs static config_pair_t const config_0_attribute_list[] = { { EGL_BUFFER_SIZE, 16 }, { EGL_ALPHA_SIZE, 0 }, @@ -981,8 +1000,32 @@ static config_pair_t const config_1_attribute_list[] = { { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, }; +// RGB 888 configs static config_pair_t const config_2_attribute_list[] = { { EGL_BUFFER_SIZE, 32 }, + { EGL_ALPHA_SIZE, 0 }, + { EGL_BLUE_SIZE, 8 }, + { EGL_GREEN_SIZE, 8 }, + { EGL_RED_SIZE, 8 }, + { EGL_DEPTH_SIZE, 0 }, + { EGL_CONFIG_ID, 6 }, + { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, +}; + +static config_pair_t const config_3_attribute_list[] = { + { EGL_BUFFER_SIZE, 32 }, + { EGL_ALPHA_SIZE, 0 }, + { EGL_BLUE_SIZE, 8 }, + { EGL_GREEN_SIZE, 8 }, + { EGL_RED_SIZE, 8 }, + { EGL_DEPTH_SIZE, 16 }, + { EGL_CONFIG_ID, 7 }, + { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, +}; + +// 8888 configs +static config_pair_t const config_4_attribute_list[] = { + { EGL_BUFFER_SIZE, 32 }, { EGL_ALPHA_SIZE, 8 }, { EGL_BLUE_SIZE, 8 }, { EGL_GREEN_SIZE, 8 }, @@ -992,7 +1035,7 @@ static config_pair_t const config_2_attribute_list[] = { { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, }; -static config_pair_t const config_3_attribute_list[] = { +static config_pair_t const config_5_attribute_list[] = { { EGL_BUFFER_SIZE, 32 }, { EGL_ALPHA_SIZE, 8 }, { EGL_BLUE_SIZE, 8 }, @@ -1003,7 +1046,8 @@ static config_pair_t const config_3_attribute_list[] = { { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, }; -static config_pair_t const config_4_attribute_list[] = { +// A8 configs +static config_pair_t const config_6_attribute_list[] = { { EGL_BUFFER_SIZE, 8 }, { EGL_ALPHA_SIZE, 8 }, { EGL_BLUE_SIZE, 0 }, @@ -1014,7 +1058,7 @@ static config_pair_t const config_4_attribute_list[] = { { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT }, }; -static config_pair_t const config_5_attribute_list[] = { +static config_pair_t const config_7_attribute_list[] = { { EGL_BUFFER_SIZE, 8 }, { EGL_ALPHA_SIZE, 8 }, { EGL_BLUE_SIZE, 0 }, @@ -1032,6 +1076,8 @@ static configs_t const gConfigs[] = { { config_3_attribute_list, NELEM(config_3_attribute_list) }, { config_4_attribute_list, NELEM(config_4_attribute_list) }, { config_5_attribute_list, NELEM(config_5_attribute_list) }, + { config_6_attribute_list, NELEM(config_6_attribute_list) }, + { config_7_attribute_list, NELEM(config_7_attribute_list) }, }; static config_management_t const gConfigManagement[] = { @@ -1062,14 +1108,66 @@ static config_management_t const gConfigManagement[] = { { EGL_BIND_TO_TEXTURE_RGB, config_management_t::exact }, { EGL_MIN_SWAP_INTERVAL, config_management_t::exact }, { EGL_MAX_SWAP_INTERVAL, config_management_t::exact }, + { EGL_LUMINANCE_SIZE, config_management_t::atLeast }, + { EGL_ALPHA_MASK_SIZE, config_management_t::atLeast }, + { EGL_COLOR_BUFFER_TYPE, config_management_t::exact }, + { EGL_RENDERABLE_TYPE, config_management_t::mask }, + { EGL_CONFORMANT, config_management_t::mask } }; + static config_pair_t const config_defaults[] = { - { EGL_SURFACE_TYPE, EGL_WINDOW_BIT }, + // attributes that are not specified are simply ignored, if a particular + // one needs not be ignored, it must be specified here, eg: + // { EGL_SURFACE_TYPE, EGL_WINDOW_BIT }, }; // ---------------------------------------------------------------------------- +static status_t getConfigFormatInfo(EGLint configID, + int32_t& pixelFormat, int32_t& depthFormat) +{ + switch(configID) { + case 0: + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + depthFormat = 0; + break; + case 1: + pixelFormat = GGL_PIXEL_FORMAT_RGB_565; + depthFormat = GGL_PIXEL_FORMAT_Z_16; + break; + case 2: + pixelFormat = GGL_PIXEL_FORMAT_RGBX_8888; + depthFormat = 0; + break; + case 3: + pixelFormat = GGL_PIXEL_FORMAT_RGBX_8888; + depthFormat = GGL_PIXEL_FORMAT_Z_16; + break; + case 4: + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + depthFormat = 0; + break; + case 5: + pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; + depthFormat = GGL_PIXEL_FORMAT_Z_16; + break; + case 6: + pixelFormat = GGL_PIXEL_FORMAT_A_8; + depthFormat = 0; + break; + case 7: + pixelFormat = GGL_PIXEL_FORMAT_A_8; + depthFormat = GGL_PIXEL_FORMAT_Z_16; + break; + default: + return NAME_NOT_FOUND; + } + return NO_ERROR; +} + +// ---------------------------------------------------------------------------- + template<typename T> static int binarySearch(T const sortedArray[], int first, int last, EGLint key) { @@ -1213,32 +1311,7 @@ static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config, int32_t depthFormat; int32_t pixelFormat; - switch(configID) { - case 0: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; - depthFormat = 0; - break; - case 1: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - case 2: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; - depthFormat = 0; - break; - case 3: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - case 4: - pixelFormat = GGL_PIXEL_FORMAT_A_8; - depthFormat = 0; - break; - case 5: - pixelFormat = GGL_PIXEL_FORMAT_A_8; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - default: + if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) { return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); } @@ -1287,32 +1360,7 @@ static EGLSurface createPixmapSurface(EGLDisplay dpy, EGLConfig config, int32_t depthFormat; int32_t pixelFormat; - switch(configID) { - case 0: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; - depthFormat = 0; - break; - case 1: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - case 2: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; - depthFormat = 0; - break; - case 3: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - case 4: - pixelFormat = GGL_PIXEL_FORMAT_A_8; - depthFormat = 0; - break; - case 5: - pixelFormat = GGL_PIXEL_FORMAT_A_8; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - default: + if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) { return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); } @@ -1351,32 +1399,7 @@ static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, int32_t depthFormat; int32_t pixelFormat; - switch(configID) { - case 0: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; - depthFormat = 0; - break; - case 1: - pixelFormat = GGL_PIXEL_FORMAT_RGB_565; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - case 2: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; - depthFormat = 0; - break; - case 3: - pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - case 4: - pixelFormat = GGL_PIXEL_FORMAT_A_8; - depthFormat = 0; - break; - case 5: - pixelFormat = GGL_PIXEL_FORMAT_A_8; - depthFormat = GGL_PIXEL_FORMAT_Z_16; - break; - default: + if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) { return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); } @@ -1513,7 +1536,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, numAttributes++; EGLint attr = *attrib_list++; EGLint val = *attrib_list++; - for (int i=0 ; i<numConfigs ; i++) { + for (int i=0 ; possibleMatch && i<numConfigs ; i++) { if (!(possibleMatch & (1<<i))) continue; if (isAttributeMatching(i, attr, val) == 0) { @@ -1523,15 +1546,15 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, } // now, handle the attributes which have a useful default value - for (size_t j=0 ; j<NELEM(config_defaults) ; j++) { - // see if this attribute was specified, if not apply its + for (size_t j=0 ; possibleMatch && j<NELEM(config_defaults) ; j++) { + // see if this attribute was specified, if not, apply its // default value if (binarySearch<config_pair_t>( (config_pair_t const*)attrib_list, 0, numAttributes-1, config_defaults[j].key) < 0) { - for (int i=0 ; i<numConfigs ; i++) { + for (int i=0 ; possibleMatch && i<numConfigs ; i++) { if (!(possibleMatch & (1<<i))) continue; if (isAttributeMatching(i, diff --git a/opengl/libagl/matrix.cpp b/opengl/libagl/matrix.cpp index 21ef50e..3c50977 100644 --- a/opengl/libagl/matrix.cpp +++ b/opengl/libagl/matrix.cpp @@ -741,20 +741,19 @@ void point4__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) { void point4__mvui(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) { // this used for transforming light positions back to object space. - // Lights have 3 components positions, so w is always 1. - // however, it is used as a switch for directional lights, so we need + // w is used as a switch for directional lights, so we need // to preserve it. const GLfixed* const m = mx->matrix.m; const GLfixed rx = rhs->x; const GLfixed ry = rhs->y; const GLfixed rz = rhs->z; - lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); - lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]); - lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]); - lhs->w = rhs->w; + const GLfixed rw = rhs->w; + lhs->x = mla4(rx, m[ 0], ry, m[ 4], rz, m[ 8], rw, m[12]); + lhs->y = mla4(rx, m[ 1], ry, m[ 5], rz, m[ 9], rw, m[13]); + lhs->z = mla4(rx, m[ 2], ry, m[ 6], rz, m[10], rw, m[14]); + lhs->w = rw; } - void point2__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) { lhs->z = 0; lhs->w = 0x10000; diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp index a59b3b0..0f1f27d 100644 --- a/opengl/libagl/state.cpp +++ b/opengl/libagl/state.cpp @@ -37,7 +37,7 @@ namespace android { // ---------------------------------------------------------------------------- static char const * const gVendorString = "Android"; -static char const * const gRendererString = "Android PixelFlinger 1.1"; +static char const * const gRendererString = "Android PixelFlinger 1.2"; static char const * const gVersionString = "OpenGL ES-CM 1.0"; static char const * const gExtensionsString = "GL_OES_byte_coordinates " // OK diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 90e6d29..13d078e 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -1252,6 +1252,11 @@ void glTexSubImage2D( ogles_error(c, GL_INVALID_OPERATION); return; } + + if (format != tex->internalformat) { + ogles_error(c, GL_INVALID_OPERATION); + return; + } if ((xoffset + width > GLsizei(surface.width)) || (yoffset + height > GLsizei(surface.height))) { ogles_error(c, GL_INVALID_VALUE); diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index 9578452..6d20e80 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -32,6 +32,10 @@ ifeq ($(TARGET_BOARD_PLATFORM),msm7k) LOCAL_CFLAGS += -DADRENO130=1 endif +ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) + LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER +endif + include $(BUILD_SHARED_LIBRARY) installed_libEGL := $(LOCAL_INSTALLED_MODULE) @@ -78,6 +82,10 @@ LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv1\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden +ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) + LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER +endif + include $(BUILD_SHARED_LIBRARY) @@ -107,4 +115,8 @@ LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv2\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden +ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) + LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER +endif + include $(BUILD_SHARED_LIBRARY) diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 7e7da1b..5d6ac26 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -128,7 +128,7 @@ const char* Loader::getTag(int dpy, int impl) return 0; } -void* Loader::open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks) +void* Loader::open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx) { /* * TODO: if we don't find display/0, then use 0/0 @@ -144,22 +144,22 @@ void* Loader::open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks) char const* tag = getTag(index, impl); if (tag) { snprintf(path, PATH_MAX, format, "GLES", tag); - dso = load_driver(path, hooks, EGL | GLESv1_CM | GLESv2); + dso = load_driver(path, cnx, EGL | GLESv1_CM | GLESv2); if (dso) { hnd = new driver_t(dso); } else { // Always load EGL first snprintf(path, PATH_MAX, format, "EGL", tag); - dso = load_driver(path, hooks, EGL); + dso = load_driver(path, cnx, EGL); if (dso) { hnd = new driver_t(dso); // TODO: make this more automated snprintf(path, PATH_MAX, format, "GLESv1_CM", tag); - hnd->set( load_driver(path, hooks, GLESv1_CM), GLESv1_CM ); + hnd->set( load_driver(path, cnx, GLESv1_CM), GLESv1_CM ); snprintf(path, PATH_MAX, format, "GLESv2", tag); - hnd->set( load_driver(path, hooks, GLESv2), GLESv2 ); + hnd->set( load_driver(path, cnx, GLESv2), GLESv2 ); } } } @@ -223,7 +223,7 @@ void Loader::init_api(void* dso, } void *Loader::load_driver(const char* driver_absolute_path, - gl_hooks_t* hooks, uint32_t mask) + egl_connection_t* cnx, uint32_t mask) { if (access(driver_absolute_path, R_OK)) { // this happens often, we don't want to log an error @@ -245,7 +245,7 @@ void *Loader::load_driver(const char* driver_absolute_path, LOGE_IF(!getProcAddress, "can't find eglGetProcAddress() in %s", driver_absolute_path); - gl_hooks_t::egl_t* egl = &hooks->egl; + egl_t* egl = &cnx->egl; __eglMustCastToProperFunctionPointerType* curr = (__eglMustCastToProperFunctionPointerType*)egl; char const * const * api = egl_names; @@ -266,14 +266,16 @@ void *Loader::load_driver(const char* driver_absolute_path, } if (mask & GLESv1_CM) { - init_api(dso, gl_names, - (__eglMustCastToProperFunctionPointerType*)&hooks->gl, - getProcAddress); + init_api(dso, gl_names, + (__eglMustCastToProperFunctionPointerType*) + &cnx->hooks[GLESv1_INDEX]->gl, + getProcAddress); } if (mask & GLESv2) { - init_api(dso, gl2_names, - (__eglMustCastToProperFunctionPointerType*)&hooks->gl2, + init_api(dso, gl_names, + (__eglMustCastToProperFunctionPointerType*) + &cnx->hooks[GLESv2_INDEX]->gl, getProcAddress); } diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h index 69f6dd5..8659b0b 100644 --- a/opengl/libs/EGL/Loader.h +++ b/opengl/libs/EGL/Loader.h @@ -32,7 +32,7 @@ namespace android { // ---------------------------------------------------------------------------- -struct gl_hooks_t; +struct egl_connection_t; class Loader : public Singleton<Loader> { @@ -69,12 +69,12 @@ class Loader : public Singleton<Loader> public: ~Loader(); - void* open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks); + void* open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx); status_t close(void* driver); private: Loader(); - void *load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask); + void *load_driver(const char* driver, egl_connection_t* cnx, uint32_t mask); static __attribute__((noinline)) void init_api(void* dso, diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index d1ddcd3..c22c21b 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -164,7 +164,7 @@ struct egl_display_t { }; uint32_t magic; - DisplayImpl disp[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; + DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS]; EGLint numTotalConfigs; volatile int32_t refs; @@ -195,8 +195,9 @@ struct egl_context_t : public egl_object_t typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref; egl_context_t(EGLDisplay dpy, EGLContext context, - int impl, egl_connection_t const* cnx) - : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx) + int impl, egl_connection_t const* cnx, int version) + : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx), + version(version) { } EGLDisplay dpy; @@ -205,6 +206,7 @@ struct egl_context_t : public egl_object_t EGLSurface draw; int impl; egl_connection_t const* cnx; + int version; }; struct egl_image_t : public egl_object_t @@ -218,7 +220,7 @@ struct egl_image_t : public egl_object_t } EGLDisplay dpy; EGLConfig context; - EGLImageKHR images[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; + EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS]; }; typedef egl_surface_t::Ref SurfaceRef; @@ -236,14 +238,15 @@ struct tls_t // ---------------------------------------------------------------------------- -egl_connection_t gEGLImpl[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; +egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS]; static egl_display_t gDisplay[NUM_DISPLAYS]; static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t gEGLThreadLocalStorageKey = -1; // ---------------------------------------------------------------------------- -EGLAPI gl_hooks_t gHooks[IMPL_NUM_IMPLEMENTATIONS]; +EGLAPI gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS]; +EGLAPI gl_hooks_t gHooksNoContext; EGLAPI pthread_key_t gGLWrapperKey = -1; // ---------------------------------------------------------------------------- @@ -434,10 +437,10 @@ static void early_egl_init(void) #endif uint32_t addr = (uint32_t)((void*)gl_no_context); android_memset32( - (uint32_t*)(void*)&gHooks[IMPL_NO_CONTEXT], + (uint32_t*)(void*)&gHooksNoContext, addr, - sizeof(gHooks[IMPL_NO_CONTEXT])); - setGlThreadSpecific(&gHooks[IMPL_NO_CONTEXT]); + sizeof(gHooksNoContext)); + setGlThreadSpecific(&gHooksNoContext); } static pthread_once_t once_control = PTHREAD_ONCE_INIT; @@ -479,7 +482,7 @@ static egl_connection_t* validate_display_config( if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL); impl = uintptr_t(config)>>24; - if (uint32_t(impl) >= IMPL_NUM_DRIVERS_IMPLEMENTATIONS) { + if (uint32_t(impl) >= IMPL_NUM_IMPLEMENTATIONS) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); } index = uintptr_t(config) & 0xFFFFFF; @@ -559,10 +562,11 @@ EGLBoolean egl_init_drivers_locked() cnx = &gEGLImpl[IMPL_SOFTWARE]; if (cnx->dso == 0) { - cnx->hooks = &gHooks[IMPL_SOFTWARE]; - cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 0, cnx->hooks); + cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_SOFTWARE]; + cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_SOFTWARE]; + cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 0, cnx); if (cnx->dso) { - EGLDisplay dpy = cnx->hooks->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); + EGLDisplay dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); LOGE_IF(dpy==EGL_NO_DISPLAY, "No EGLDisplay for software EGL!"); d->disp[IMPL_SOFTWARE].dpy = dpy; if (dpy == EGL_NO_DISPLAY) { @@ -577,10 +581,11 @@ EGLBoolean egl_init_drivers_locked() char value[PROPERTY_VALUE_MAX]; property_get("debug.egl.hw", value, "1"); if (atoi(value) != 0) { - cnx->hooks = &gHooks[IMPL_HARDWARE]; - cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 1, cnx->hooks); + cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_HARDWARE]; + cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_HARDWARE]; + cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 1, cnx); if (cnx->dso) { - EGLDisplay dpy = cnx->hooks->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); + EGLDisplay dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); LOGE_IF(dpy==EGL_NO_DISPLAY, "No EGLDisplay for hardware EGL!"); d->disp[IMPL_HARDWARE].dpy = dpy; if (dpy == EGL_NO_DISPLAY) { @@ -645,12 +650,12 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) return EGL_TRUE; } - setGlThreadSpecific(&gHooks[IMPL_NO_CONTEXT]); + setGlThreadSpecific(&gHooksNoContext); // initialize each EGL and // build our own extension string first, based on the extension we know // and the extension supported by our client implementation - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; cnx->major = -1; cnx->minor = -1; @@ -668,13 +673,13 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) */ if (i == IMPL_HARDWARE) { dp->disp[i].dpy = - cnx->hooks->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); + cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); } #endif EGLDisplay idpy = dp->disp[i].dpy; - if (cnx->hooks->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) { + if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) { //LOGD("initialized %d dpy=%p, ver=%d.%d, cnx=%p", // i, idpy, cnx->major, cnx->minor, cnx); @@ -683,29 +688,29 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) // get the query-strings for this display for each implementation dp->disp[i].queryString.vendor = - cnx->hooks->egl.eglQueryString(idpy, EGL_VENDOR); + cnx->egl.eglQueryString(idpy, EGL_VENDOR); dp->disp[i].queryString.version = - cnx->hooks->egl.eglQueryString(idpy, EGL_VERSION); + cnx->egl.eglQueryString(idpy, EGL_VERSION); dp->disp[i].queryString.extensions = - cnx->hooks->egl.eglQueryString(idpy, EGL_EXTENSIONS); + cnx->egl.eglQueryString(idpy, EGL_EXTENSIONS); dp->disp[i].queryString.clientApi = - cnx->hooks->egl.eglQueryString(idpy, EGL_CLIENT_APIS); + cnx->egl.eglQueryString(idpy, EGL_CLIENT_APIS); } else { LOGW("%d: eglInitialize(%p) failed (%s)", i, idpy, - egl_strerror(cnx->hooks->egl.eglGetError())); + egl_strerror(cnx->egl.eglGetError())); } } EGLBoolean res = EGL_FALSE; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso && cnx->major>=0 && cnx->minor>=0) { EGLint n; - if (cnx->hooks->egl.eglGetConfigs(dp->disp[i].dpy, 0, 0, &n)) { + if (cnx->egl.eglGetConfigs(dp->disp[i].dpy, 0, 0, &n)) { dp->disp[i].config = (EGLConfig*)malloc(sizeof(EGLConfig)*n); if (dp->disp[i].config) { - if (cnx->hooks->egl.eglGetConfigs( + if (cnx->egl.eglGetConfigs( dp->disp[i].dpy, dp->disp[i].config, n, &dp->disp[i].numConfigs)) { @@ -742,12 +747,12 @@ EGLBoolean eglTerminate(EGLDisplay dpy) return EGL_TRUE; EGLBoolean res = EGL_FALSE; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso && dp->disp[i].state == egl_display_t::INITIALIZED) { - if (cnx->hooks->egl.eglTerminate(dp->disp[i].dpy) == EGL_FALSE) { + if (cnx->egl.eglTerminate(dp->disp[i].dpy) == EGL_FALSE) { LOGW("%d: eglTerminate(%p) failed (%s)", i, dp->disp[i].dpy, - egl_strerror(cnx->hooks->egl.eglGetError())); + egl_strerror(cnx->egl.eglGetError())); } // REVISIT: it's unclear what to do if eglTerminate() fails free(dp->disp[i].config); @@ -784,7 +789,7 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy, return EGL_TRUE; } GLint n = 0; - for (int j=0 ; j<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; j++) { + for (int j=0 ; j<IMPL_NUM_IMPLEMENTATIONS ; j++) { for (int i=0 ; i<dp->disp[j].numConfigs && config_size ; i++) { *configs++ = MAKE_CONFIG(j, i); config_size--; @@ -841,7 +846,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { - cnx->hooks->egl.eglGetConfigAttrib( + cnx->egl.eglGetConfigAttrib( dp->disp[i].dpy, dp->disp[i].config[index], EGL_CONFIG_ID, &configId); @@ -851,12 +856,12 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, // At this point, the only configuration that can match is // dp->configs[i][index], however, we don't know if it would be // rejected because of the other attributes, so we do have to call - // cnx->hooks->egl.eglChooseConfig() -- but we don't have to loop + // cnx->egl.eglChooseConfig() -- but we don't have to loop // through all the EGLimpl[]. // We also know we can only get a single config back, and we know // which one. - res = cnx->hooks->egl.eglChooseConfig( + res = cnx->egl.eglChooseConfig( dp->disp[i].dpy, attrib_list, configs, config_size, &n); if (res && n>0) { // n has to be 0 or 1, by construction, and we already know @@ -872,10 +877,10 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, return res; } - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { - if (cnx->hooks->egl.eglChooseConfig( + if (cnx->egl.eglChooseConfig( dp->disp[i].dpy, attrib_list, configs, config_size, &n)) { if (configs) { // now we need to convert these client EGLConfig to our @@ -917,7 +922,7 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, *value = configToUniqueId(dp, i, index); return EGL_TRUE; } - return cnx->hooks->egl.eglGetConfigAttrib( + return cnx->egl.eglGetConfigAttrib( dp->disp[i].dpy, dp->disp[i].config[index], attribute, value); } @@ -933,7 +938,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { - EGLSurface surface = cnx->hooks->egl.eglCreateWindowSurface( + EGLSurface surface = cnx->egl.eglCreateWindowSurface( dp->disp[i].dpy, dp->disp[i].config[index], window, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); @@ -951,7 +956,7 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { - EGLSurface surface = cnx->hooks->egl.eglCreatePixmapSurface( + EGLSurface surface = cnx->egl.eglCreatePixmapSurface( dp->disp[i].dpy, dp->disp[i].config[index], pixmap, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); @@ -968,7 +973,7 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { - EGLSurface surface = cnx->hooks->egl.eglCreatePbufferSurface( + EGLSurface surface = cnx->egl.eglCreatePbufferSurface( dp->disp[i].dpy, dp->disp[i].config[index], attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); @@ -988,7 +993,7 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) egl_display_t const * const dp = get_display(dpy); egl_surface_t * const s = get_surface(surface); - EGLBoolean result = s->cnx->hooks->egl.eglDestroySurface( + EGLBoolean result = s->cnx->egl.eglDestroySurface( dp->disp[s->impl].dpy, s->surface); if (result == EGL_TRUE) { _s.terminate(); @@ -1007,7 +1012,7 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - return s->cnx->hooks->egl.eglQuerySurface( + return s->cnx->egl.eglQuerySurface( dp->disp[s->impl].dpy, s->surface, attribute, value); } @@ -1022,11 +1027,26 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { - EGLContext context = cnx->hooks->egl.eglCreateContext( + EGLContext context = cnx->egl.eglCreateContext( dp->disp[i].dpy, dp->disp[i].config[index], share_list, attrib_list); if (context != EGL_NO_CONTEXT) { - egl_context_t* c = new egl_context_t(dpy, context, i, cnx); + // figure out if it's a GLESv1 or GLESv2 + int version = 0; + if (attrib_list) { + while (*attrib_list != EGL_NONE) { + GLint attr = *attrib_list++; + GLint value = *attrib_list++; + if (attr == EGL_CONTEXT_CLIENT_VERSION) { + if (value == 1) { + version = GLESv1_INDEX; + } else if (value == 2) { + version = GLESv2_INDEX; + } + } + }; + } + egl_context_t* c = new egl_context_t(dpy, context, i, cnx, version); return c; } } @@ -1042,7 +1062,7 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) return EGL_FALSE; egl_display_t const * const dp = get_display(dpy); egl_context_t * const c = get_context(ctx); - EGLBoolean result = c->cnx->hooks->egl.eglDestroyContext( + EGLBoolean result = c->cnx->egl.eglDestroyContext( dp->disp[c->impl].dpy, c->context); if (result == EGL_TRUE) { _c.terminate(); @@ -1122,10 +1142,10 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, EGLBoolean result; if (c) { - result = c->cnx->hooks->egl.eglMakeCurrent( + result = c->cnx->egl.eglMakeCurrent( dp->disp[c->impl].dpy, impl_draw, impl_read, impl_ctx); } else { - result = cur_c->cnx->hooks->egl.eglMakeCurrent( + result = cur_c->cnx->egl.eglMakeCurrent( dp->disp[cur_c->impl].dpy, impl_draw, impl_read, impl_ctx); } @@ -1138,11 +1158,11 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, // cur_c has to be valid here (but could be terminated) if (ctx != EGL_NO_CONTEXT) { - setGlThreadSpecific(c->cnx->hooks); + setGlThreadSpecific(c->cnx->hooks[c->version]); setContext(ctx); _c.acquire(); } else { - setGlThreadSpecific(&gHooks[IMPL_NO_CONTEXT]); + setGlThreadSpecific(&gHooksNoContext); setContext(EGL_NO_CONTEXT); } _cur_c.release(); @@ -1171,7 +1191,7 @@ EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx, egl_display_t const * const dp = get_display(dpy); egl_context_t * const c = get_context(ctx); - return c->cnx->hooks->egl.eglQueryContext( + return c->cnx->egl.eglQueryContext( dp->disp[c->impl].dpy, c->context, attribute, value); } @@ -1231,7 +1251,7 @@ EGLBoolean eglWaitGL(void) egl_connection_t* const cnx = &gEGLImpl[c->impl]; if (!cnx->dso) return setError(EGL_BAD_CONTEXT, EGL_FALSE); - res = cnx->hooks->egl.eglWaitGL(); + res = cnx->egl.eglWaitGL(); } return res; } @@ -1251,7 +1271,7 @@ EGLBoolean eglWaitNative(EGLint engine) egl_connection_t* const cnx = &gEGLImpl[c->impl]; if (!cnx->dso) return setError(EGL_BAD_CONTEXT, EGL_FALSE); - res = cnx->hooks->egl.eglWaitNative(engine); + res = cnx->egl.eglWaitNative(engine); } return res; } @@ -1259,11 +1279,11 @@ EGLBoolean eglWaitNative(EGLint engine) EGLint eglGetError(void) { EGLint result = EGL_SUCCESS; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { EGLint err = EGL_SUCCESS; egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) - err = cnx->hooks->egl.eglGetError(); + err = cnx->egl.eglGetError(); if (err!=EGL_SUCCESS && result==EGL_SUCCESS) result = err; } @@ -1294,11 +1314,11 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) addr = 0; int slot = -1; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { - if (cnx->hooks->egl.eglGetProcAddress) { - addr = cnx->hooks->egl.eglGetProcAddress(procname); + if (cnx->egl.eglGetProcAddress) { + addr = cnx->egl.eglGetProcAddress(procname); if (addr) { if (slot == -1) { slot = 0; // XXX: find free slot @@ -1307,7 +1327,7 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) break; } } - cnx->hooks->ext.extensions[slot] = addr; + //cnx->hooks->ext.extensions[slot] = addr; } } } @@ -1347,7 +1367,7 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) return EGL_FALSE; egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(draw); - return s->cnx->hooks->egl.eglSwapBuffers(dp->disp[s->impl].dpy, s->surface); + return s->cnx->egl.eglSwapBuffers(dp->disp[s->impl].dpy, s->surface); } EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface, @@ -1360,7 +1380,7 @@ EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface, return EGL_FALSE; egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - return s->cnx->hooks->egl.eglCopyBuffers( + return s->cnx->egl.eglCopyBuffers( dp->disp[s->impl].dpy, s->surface, target); } @@ -1395,8 +1415,8 @@ EGLBoolean eglSurfaceAttrib( return EGL_FALSE; egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - if (s->cnx->hooks->egl.eglSurfaceAttrib) { - return s->cnx->hooks->egl.eglSurfaceAttrib( + if (s->cnx->egl.eglSurfaceAttrib) { + return s->cnx->egl.eglSurfaceAttrib( dp->disp[s->impl].dpy, s->surface, attribute, value); } return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1412,8 +1432,8 @@ EGLBoolean eglBindTexImage( return EGL_FALSE; egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - if (s->cnx->hooks->egl.eglBindTexImage) { - return s->cnx->hooks->egl.eglBindTexImage( + if (s->cnx->egl.eglBindTexImage) { + return s->cnx->egl.eglBindTexImage( dp->disp[s->impl].dpy, s->surface, buffer); } return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1429,8 +1449,8 @@ EGLBoolean eglReleaseTexImage( return EGL_FALSE; egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - if (s->cnx->hooks->egl.eglReleaseTexImage) { - return s->cnx->hooks->egl.eglReleaseTexImage( + if (s->cnx->egl.eglReleaseTexImage) { + return s->cnx->egl.eglReleaseTexImage( dp->disp[s->impl].dpy, s->surface, buffer); } return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1442,11 +1462,11 @@ EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); EGLBoolean res = EGL_TRUE; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { - if (cnx->hooks->egl.eglSwapInterval) { - if (cnx->hooks->egl.eglSwapInterval( + if (cnx->egl.eglSwapInterval) { + if (cnx->egl.eglSwapInterval( dp->disp[i].dpy, interval) == EGL_FALSE) { res = EGL_FALSE; } @@ -1475,10 +1495,10 @@ EGLBoolean eglWaitClient(void) egl_connection_t* const cnx = &gEGLImpl[c->impl]; if (!cnx->dso) return setError(EGL_BAD_CONTEXT, EGL_FALSE); - if (cnx->hooks->egl.eglWaitClient) { - res = cnx->hooks->egl.eglWaitClient(); + if (cnx->egl.eglWaitClient) { + res = cnx->egl.eglWaitClient(); } else { - res = cnx->hooks->egl.eglWaitGL(); + res = cnx->egl.eglWaitGL(); } } return res; @@ -1492,11 +1512,11 @@ EGLBoolean eglBindAPI(EGLenum api) // bind this API on all EGLs EGLBoolean res = EGL_TRUE; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { - if (cnx->hooks->egl.eglBindAPI) { - if (cnx->hooks->egl.eglBindAPI(api) == EGL_FALSE) { + if (cnx->egl.eglBindAPI) { + if (cnx->egl.eglBindAPI(api) == EGL_FALSE) { res = EGL_FALSE; } } @@ -1511,13 +1531,13 @@ EGLenum eglQueryAPI(void) return setError(EGL_BAD_PARAMETER, EGL_FALSE); } - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { - if (cnx->hooks->egl.eglQueryAPI) { + if (cnx->egl.eglQueryAPI) { // the first one we find is okay, because they all // should be the same - return cnx->hooks->egl.eglQueryAPI(); + return cnx->egl.eglQueryAPI(); } } } @@ -1527,11 +1547,11 @@ EGLenum eglQueryAPI(void) EGLBoolean eglReleaseThread(void) { - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { - if (cnx->hooks->egl.eglReleaseThread) { - cnx->hooks->egl.eglReleaseThread(); + if (cnx->egl.eglReleaseThread) { + cnx->egl.eglReleaseThread(); } } } @@ -1547,8 +1567,8 @@ EGLSurface eglCreatePbufferFromClientBuffer( int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (!cnx) return EGL_FALSE; - if (cnx->hooks->egl.eglCreatePbufferFromClientBuffer) { - return cnx->hooks->egl.eglCreatePbufferFromClientBuffer( + if (cnx->egl.eglCreatePbufferFromClientBuffer) { + return cnx->egl.eglCreatePbufferFromClientBuffer( dp->disp[i].dpy, buftype, buffer, dp->disp[i].config[index], attrib_list); } @@ -1571,8 +1591,8 @@ EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - if (s->cnx->hooks->egl.eglLockSurfaceKHR) { - return s->cnx->hooks->egl.eglLockSurfaceKHR( + if (s->cnx->egl.eglLockSurfaceKHR) { + return s->cnx->egl.eglLockSurfaceKHR( dp->disp[s->impl].dpy, s->surface, attrib_list); } return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -1589,8 +1609,8 @@ EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - if (s->cnx->hooks->egl.eglUnlockSurfaceKHR) { - return s->cnx->hooks->egl.eglUnlockSurfaceKHR( + if (s->cnx->egl.eglUnlockSurfaceKHR) { + return s->cnx->egl.eglUnlockSurfaceKHR( dp->disp[s->impl].dpy, s->surface); } return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -1607,7 +1627,7 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, egl_display_t const * const dp = get_display(dpy); egl_context_t * const c = get_context(ctx); // since we have an EGLContext, we know which implementation to use - EGLImageKHR image = c->cnx->hooks->egl.eglCreateImageKHR( + EGLImageKHR image = c->cnx->egl.eglCreateImageKHR( dp->disp[c->impl].dpy, c->context, target, buffer, attrib_list); if (image == EGL_NO_IMAGE_KHR) return image; @@ -1621,17 +1641,22 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, if (dp == 0) { return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR); } - // since we don't have a way to know which implementation to call, - // we're calling all of them - EGLImageKHR implImages[IMPL_NUM_DRIVERS_IMPLEMENTATIONS]; + /* Since we don't have a way to know which implementation to call, + * we're calling all of them. If at least one of the implementation + * succeeded, this is a success. + */ + + EGLint currentError = eglGetError(); + + EGLImageKHR implImages[IMPL_NUM_IMPLEMENTATIONS]; bool success = false; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; implImages[i] = EGL_NO_IMAGE_KHR; if (cnx->dso) { - if (cnx->hooks->egl.eglCreateImageKHR) { - implImages[i] = cnx->hooks->egl.eglCreateImageKHR( + if (cnx->egl.eglCreateImageKHR) { + implImages[i] = cnx->egl.eglCreateImageKHR( dp->disp[i].dpy, ctx, target, buffer, attrib_list); if (implImages[i] != EGL_NO_IMAGE_KHR) { success = true; @@ -1639,9 +1664,24 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, } } } - if (!success) + + if (!success) { + // failure, if there was an error when we entered this function, + // the error flag must not be updated. + // Otherwise, the error is whatever happened in the implementation + // that faulted. + if (currentError != EGL_SUCCESS) { + setError(currentError, EGL_NO_IMAGE_KHR); + } return EGL_NO_IMAGE_KHR; - + } else { + // In case of success, we need to clear all error flags + // (especially those caused by the implementation that didn't + // succeed). TODO: we could avoid this if we knew this was + // a "full" success (all implementation succeeded). + eglGetError(); + } + egl_image_t* result = new egl_image_t(dpy, ctx); memcpy(result->images, implImages, sizeof(implImages)); return (EGLImageKHR)result; @@ -1660,12 +1700,12 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) egl_image_t* image = get_image(img); bool success = false; - for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) { + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (image->images[i] != EGL_NO_IMAGE_KHR) { if (cnx->dso) { - if (cnx->hooks->egl.eglCreateImageKHR) { - if (cnx->hooks->egl.eglDestroyImageKHR( + if (cnx->egl.eglCreateImageKHR) { + if (cnx->egl.eglDestroyImageKHR( dp->disp[i].dpy, image->images[i])) { success = true; } @@ -1696,8 +1736,8 @@ EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, return EGL_FALSE; egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(draw); - if (s->cnx->hooks->egl.eglSetSwapRectangleANDROID) { - return s->cnx->hooks->egl.eglSetSwapRectangleANDROID( + if (s->cnx->egl.eglSetSwapRectangleANDROID) { + return s->cnx->egl.eglSetSwapRectangleANDROID( dp->disp[s->impl].dpy, s->surface, left, top, width, height); } return setError(EGL_BAD_DISPLAY, NULL); @@ -1712,8 +1752,8 @@ EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw) return 0; egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(draw); - if (s->cnx->hooks->egl.eglGetRenderBufferANDROID) { - return s->cnx->hooks->egl.eglGetRenderBufferANDROID( + if (s->cnx->egl.eglGetRenderBufferANDROID) { + return s->cnx->egl.eglGetRenderBufferANDROID( dp->disp[s->impl].dpy, s->surface); } return setError(EGL_BAD_DISPLAY, (EGLClientBuffer*)0); diff --git a/opengl/libs/EGL/hooks.cpp b/opengl/libs/EGL/hooks.cpp index 2246366..72ad6b3 100644 --- a/opengl/libs/EGL/hooks.cpp +++ b/opengl/libs/EGL/hooks.cpp @@ -41,14 +41,7 @@ void gl_unimplemented() { #define EGL_ENTRY(_r, _api, ...) #_api, char const * const gl_names[] = { - #include "GLES_CM/gl_entries.in" - #include "GLES_CM/glext_entries.in" - NULL -}; - -char const * const gl2_names[] = { - #include "GLES2/gl2_entries.in" - #include "GLES2/gl2ext_entries.in" + #include "entries.in" NULL }; diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp index e5358c3..b8e3283 100644 --- a/opengl/libs/GLES2/gl2.cpp +++ b/opengl/libs/GLES2/gl2.cpp @@ -41,22 +41,30 @@ using namespace android; #if USE_FAST_TLS_KEY + #ifdef HAVE_ARM_TLS_REGISTER + #define GET_TLS(reg) \ + "mrc p15, 0, " #reg ", c13, c0, 3 \n" + #else + #define GET_TLS(reg) \ + "mov " #reg ", #0xFFFF0FFF \n" \ + "ldr " #reg ", [" #reg ", #-15] \n" + #endif + #define API_ENTRY(_api) __attribute__((naked)) _api #define CALL_GL_API(_api, ...) \ asm volatile( \ - "mov r12, #0xFFFF0FFF \n" \ - "ldr r12, [r12, #-15] \n" \ + GET_TLS(r12) \ "ldr r12, [r12, %[tls]] \n" \ "cmp r12, #0 \n" \ "ldrne pc, [r12, %[api]] \n" \ "bx lr \n" \ : \ : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ - [api] "J"(__builtin_offsetof(gl_hooks_t, gl2._api)) \ + [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ : \ ); - + #define CALL_GL_API_RETURN(_api, ...) \ CALL_GL_API(_api, __VA_ARGS__) \ return 0; // placate gcc's warnings. never reached. @@ -66,11 +74,11 @@ using namespace android; #define API_ENTRY(_api) _api #define CALL_GL_API(_api, ...) \ - gl_hooks_t::gl2_t const * const _c = &getGlThreadSpecific()->gl2; \ + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ _c->_api(__VA_ARGS__) #define CALL_GL_API_RETURN(_api, ...) \ - gl_hooks_t::gl2_t const * const _c = &getGlThreadSpecific()->gl2; \ + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ return _c->_api(__VA_ARGS__) #endif diff --git a/opengl/libs/GLES2/gl2_entries.in b/opengl/libs/GLES2/gl2_entries.in deleted file mode 100644 index 6a41b94..0000000 --- a/opengl/libs/GLES2/gl2_entries.in +++ /dev/null @@ -1,142 +0,0 @@ -GL_ENTRY(void, glActiveTexture, GLenum texture) -GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader) -GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const char* name) -GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer) -GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer) -GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer) -GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture) -GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -GL_ENTRY(void, glBlendEquation, GLenum mode ) -GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha) -GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor) -GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) -GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const void* data, GLenum usage) -GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) -GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target) -GL_ENTRY(void, glClear, GLbitfield mask) -GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -GL_ENTRY(void, glClearDepthf, GLclampf depth) -GL_ENTRY(void, glClearStencil, GLint s) -GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) -GL_ENTRY(void, glCompileShader, GLuint shader) -GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) -GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) -GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) -GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) -GL_ENTRY(GLuint, glCreateProgram, void) -GL_ENTRY(GLuint, glCreateShader, GLenum type) -GL_ENTRY(void, glCullFace, GLenum mode) -GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint* buffers) -GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers) -GL_ENTRY(void, glDeleteProgram, GLuint program) -GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers) -GL_ENTRY(void, glDeleteShader, GLuint shader) -GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint* textures) -GL_ENTRY(void, glDepthFunc, GLenum func) -GL_ENTRY(void, glDepthMask, GLboolean flag) -GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar) -GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader) -GL_ENTRY(void, glDisable, GLenum cap) -GL_ENTRY(void, glDisableVertexAttribArray, GLuint index) -GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) -GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const void* indices) -GL_ENTRY(void, glEnable, GLenum cap) -GL_ENTRY(void, glEnableVertexAttribArray, GLuint index) -GL_ENTRY(void, glFinish, void) -GL_ENTRY(void, glFlush, void) -GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) -GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) -GL_ENTRY(void, glFrontFace, GLenum mode) -GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint* buffers) -GL_ENTRY(void, glGenerateMipmap, GLenum target) -GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers) -GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers) -GL_ENTRY(void, glGenTextures, GLsizei n, GLuint* textures) -GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) -GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) -GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) -GL_ENTRY(int, glGetAttribLocation, GLuint program, const char* name) -GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean* params) -GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint* params) -GL_ENTRY(GLenum, glGetError, void) -GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat* params) -GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params) -GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint* params) -GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params) -GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) -GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) -GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params) -GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) -GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) -GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, char* source) -GL_ENTRY(const GLubyte*, glGetString, GLenum name) -GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat* params) -GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint* params) -GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params) -GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params) -GL_ENTRY(int, glGetUniformLocation, GLuint program, const char* name) -GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params) -GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params) -GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer) -GL_ENTRY(void, glHint, GLenum target, GLenum mode) -GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer) -GL_ENTRY(GLboolean, glIsEnabled, GLenum cap) -GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer) -GL_ENTRY(GLboolean, glIsProgram, GLuint program) -GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer) -GL_ENTRY(GLboolean, glIsShader, GLuint shader) -GL_ENTRY(GLboolean, glIsTexture, GLuint texture) -GL_ENTRY(void, glLineWidth, GLfloat width) -GL_ENTRY(void, glLinkProgram, GLuint program) -GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param) -GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units) -GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) -GL_ENTRY(void, glReleaseShaderCompiler, void) -GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) -GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert) -GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) -GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) -GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const char** string, const GLint* length) -GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) -GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask) -GL_ENTRY(void, glStencilMask, GLuint mask) -GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask) -GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) -GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) -GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) -GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) -GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat* params) -GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param) -GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint* params) -GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) -GL_ENTRY(void, glUniform1f, GLint location, GLfloat x) -GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* v) -GL_ENTRY(void, glUniform1i, GLint location, GLint x) -GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint* v) -GL_ENTRY(void, glUniform2f, GLint location, GLfloat x, GLfloat y) -GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* v) -GL_ENTRY(void, glUniform2i, GLint location, GLint x, GLint y) -GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint* v) -GL_ENTRY(void, glUniform3f, GLint location, GLfloat x, GLfloat y, GLfloat z) -GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* v) -GL_ENTRY(void, glUniform3i, GLint location, GLint x, GLint y, GLint z) -GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint* v) -GL_ENTRY(void, glUniform4f, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* v) -GL_ENTRY(void, glUniform4i, GLint location, GLint x, GLint y, GLint z, GLint w) -GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint* v) -GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_ENTRY(void, glUseProgram, GLuint program) -GL_ENTRY(void, glValidateProgram, GLuint program) -GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x) -GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values) -GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y) -GL_ENTRY(void, glVertexAttrib2fv, GLuint indx, const GLfloat* values) -GL_ENTRY(void, glVertexAttrib3f, GLuint indx, GLfloat x, GLfloat y, GLfloat z) -GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values) -GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values) -GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) -GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) diff --git a/opengl/libs/GLES2/gl2ext_entries.in b/opengl/libs/GLES2/gl2ext_entries.in deleted file mode 100644 index e608f5d..0000000 --- a/opengl/libs/GLES2/gl2ext_entries.in +++ /dev/null @@ -1,35 +0,0 @@ -GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image) -GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image) -GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) -GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const void *binary, GLint length) -GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access) -GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target) -GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params) -GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) -GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) -GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) -GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) -GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) -GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) -GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups) -GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) -GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, char *groupString) -GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString) -GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, void *data) -GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors) -GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors) -GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) -GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor) -GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor) -GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) -GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences) -GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences) -GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence) -GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence) -GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params) -GL_ENTRY(void, glFinishFenceNV, GLuint fence) -GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition) -GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls) -GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString) -GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl) -GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl) diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp index 1e4c136..0c9352e 100644 --- a/opengl/libs/GLES_CM/gl.cpp +++ b/opengl/libs/GLES_CM/gl.cpp @@ -76,12 +76,20 @@ void glVertexPointerBounds(GLint size, GLenum type, #if USE_FAST_TLS_KEY && !CHECK_FOR_GL_ERRORS + #ifdef HAVE_ARM_TLS_REGISTER + #define GET_TLS(reg) \ + "mrc p15, 0, " #reg ", c13, c0, 3 \n" + #else + #define GET_TLS(reg) \ + "mov " #reg ", #0xFFFF0FFF \n" \ + "ldr " #reg ", [" #reg ", #-15] \n" + #endif + #define API_ENTRY(_api) __attribute__((naked)) _api #define CALL_GL_API(_api, ...) \ asm volatile( \ - "mov r12, #0xFFFF0FFF \n" \ - "ldr r12, [r12, #-15] \n" \ + GET_TLS(r12) \ "ldr r12, [r12, %[tls]] \n" \ "cmp r12, #0 \n" \ "ldrne pc, [r12, %[api]] \n" \ @@ -91,7 +99,7 @@ void glVertexPointerBounds(GLint size, GLenum type, [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ : \ ); - + #define CALL_GL_API_RETURN(_api, ...) \ CALL_GL_API(_api, __VA_ARGS__) \ return 0; // placate gcc's warnings. never reached. diff --git a/opengl/libs/GLES_CM/gl_entries.in b/opengl/libs/GLES_CM/gl_entries.in deleted file mode 100644 index d7cc5da..0000000 --- a/opengl/libs/GLES_CM/gl_entries.in +++ /dev/null @@ -1,145 +0,0 @@ -GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref) -GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -GL_ENTRY(void, glClearDepthf, GLclampf depth) -GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation) -GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) -GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar) -GL_ENTRY(void, glFogf, GLenum pname, GLfloat param) -GL_ENTRY(void, glFogfv, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glFrustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) -GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat eqn[4]) -GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *params) -GL_ENTRY(void, glGetLightfv, GLenum light, GLenum pname, GLfloat *params) -GL_ENTRY(void, glGetMaterialfv, GLenum face, GLenum pname, GLfloat *params) -GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params) -GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat *params) -GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param) -GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glLightf, GLenum light, GLenum pname, GLfloat param) -GL_ENTRY(void, glLightfv, GLenum light, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glLineWidth, GLfloat width) -GL_ENTRY(void, glLoadMatrixf, const GLfloat *m) -GL_ENTRY(void, glMaterialf, GLenum face, GLenum pname, GLfloat param) -GL_ENTRY(void, glMaterialfv, GLenum face, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glMultMatrixf, const GLfloat *m) -GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) -GL_ENTRY(void, glNormal3f, GLfloat nx, GLfloat ny, GLfloat nz) -GL_ENTRY(void, glOrthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) -GL_ENTRY(void, glPointParameterf, GLenum pname, GLfloat param) -GL_ENTRY(void, glPointParameterfv, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glPointSize, GLfloat size) -GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units) -GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) -GL_ENTRY(void, glScalef, GLfloat x, GLfloat y, GLfloat z) -GL_ENTRY(void, glTexEnvf, GLenum target, GLenum pname, GLfloat param) -GL_ENTRY(void, glTexEnvfv, GLenum target, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) -GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z) -GL_ENTRY(void, glActiveTexture, GLenum texture) -GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref) -GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer) -GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture) -GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor) -GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) -GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) -GL_ENTRY(void, glClear, GLbitfield mask) -GL_ENTRY(void, glClearColorx, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) -GL_ENTRY(void, glClearDepthx, GLclampx depth) -GL_ENTRY(void, glClearStencil, GLint s) -GL_ENTRY(void, glClientActiveTexture, GLenum texture) -GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed *equation) -GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) -GL_ENTRY(void, glColor4x, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) -GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) -GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) -GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) -GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) -GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) -GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) -GL_ENTRY(void, glCullFace, GLenum mode) -GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers) -GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures) -GL_ENTRY(void, glDepthFunc, GLenum func) -GL_ENTRY(void, glDepthMask, GLboolean flag) -GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar) -GL_ENTRY(void, glDisable, GLenum cap) -GL_ENTRY(void, glDisableClientState, GLenum array) -GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) -GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) -GL_ENTRY(void, glEnable, GLenum cap) -GL_ENTRY(void, glEnableClientState, GLenum array) -GL_ENTRY(void, glFinish, void) -GL_ENTRY(void, glFlush, void) -GL_ENTRY(void, glFogx, GLenum pname, GLfixed param) -GL_ENTRY(void, glFogxv, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glFrontFace, GLenum mode) -GL_ENTRY(void, glFrustumx, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) -GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params) -GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params) -GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed eqn[4]) -GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint *buffers) -GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures) -GL_ENTRY(GLenum, glGetError, void) -GL_ENTRY(void, glGetFixedv, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *params) -GL_ENTRY(void, glGetLightxv, GLenum light, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetPointerv, GLenum pname, void **params) -GL_ENTRY(const GLubyte *, glGetString, GLenum name) -GL_ENTRY(void, glGetTexEnviv, GLenum env, GLenum pname, GLint *params) -GL_ENTRY(void, glGetTexEnvxv, GLenum env, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params) -GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params) -GL_ENTRY(void, glHint, GLenum target, GLenum mode) -GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer) -GL_ENTRY(GLboolean, glIsEnabled, GLenum cap) -GL_ENTRY(GLboolean, glIsTexture, GLuint texture) -GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param) -GL_ENTRY(void, glLightModelxv, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glLightx, GLenum light, GLenum pname, GLfixed param) -GL_ENTRY(void, glLightxv, GLenum light, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glLineWidthx, GLfixed width) -GL_ENTRY(void, glLoadIdentity, void) -GL_ENTRY(void, glLoadMatrixx, const GLfixed *m) -GL_ENTRY(void, glLogicOp, GLenum opcode) -GL_ENTRY(void, glMaterialx, GLenum face, GLenum pname, GLfixed param) -GL_ENTRY(void, glMaterialxv, GLenum face, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glMatrixMode, GLenum mode) -GL_ENTRY(void, glMultMatrixx, const GLfixed *m) -GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) -GL_ENTRY(void, glNormal3x, GLfixed nx, GLfixed ny, GLfixed nz) -GL_ENTRY(void, glNormalPointer, GLenum type, GLsizei stride, const GLvoid *pointer) -GL_ENTRY(void, glOrthox, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) -GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param) -GL_ENTRY(void, glPointParameterx, GLenum pname, GLfixed param) -GL_ENTRY(void, glPointParameterxv, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glPointSizex, GLfixed size) -GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units) -GL_ENTRY(void, glPopMatrix, void) -GL_ENTRY(void, glPushMatrix, void) -GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) -GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z) -GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert) -GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert) -GL_ENTRY(void, glScalex, GLfixed x, GLfixed y, GLfixed z) -GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) -GL_ENTRY(void, glShadeModel, GLenum mode) -GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) -GL_ENTRY(void, glStencilMask, GLuint mask) -GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) -GL_ENTRY(void, glTexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) -GL_ENTRY(void, glTexEnvi, GLenum target, GLenum pname, GLint param) -GL_ENTRY(void, glTexEnvx, GLenum target, GLenum pname, GLfixed param) -GL_ENTRY(void, glTexEnviv, GLenum target, GLenum pname, const GLint *params) -GL_ENTRY(void, glTexEnvxv, GLenum target, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) -GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param) -GL_ENTRY(void, glTexParameterx, GLenum target, GLenum pname, GLfixed param) -GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint *params) -GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) -GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z) -GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) -GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) -GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid *pointer) diff --git a/opengl/libs/GLES_CM/glext_entries.in b/opengl/libs/GLES_CM/glext_entries.in deleted file mode 100644 index dd09c71..0000000 --- a/opengl/libs/GLES_CM/glext_entries.in +++ /dev/null @@ -1,90 +0,0 @@ -GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha) -GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) -GL_ENTRY(void, glBlendEquationOES, GLenum mode) -GL_ENTRY(void, glDrawTexsOES, GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) -GL_ENTRY(void, glDrawTexiOES, GLint x, GLint y, GLint z, GLint width, GLint height) -GL_ENTRY(void, glDrawTexxOES, GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) -GL_ENTRY(void, glDrawTexsvOES, const GLshort *coords) -GL_ENTRY(void, glDrawTexivOES, const GLint *coords) -GL_ENTRY(void, glDrawTexxvOES, const GLfixed *coords) -GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) -GL_ENTRY(void, glDrawTexfvOES, const GLfloat *coords) -GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image) -GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image) -GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref) -GL_ENTRY(void, glClearColorxOES, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) -GL_ENTRY(void, glClearDepthxOES, GLclampx depth) -GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed *equation) -GL_ENTRY(void, glColor4xOES, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) -GL_ENTRY(void, glDepthRangexOES, GLclampx zNear, GLclampx zFar) -GL_ENTRY(void, glFogxOES, GLenum pname, GLfixed param) -GL_ENTRY(void, glFogxvOES, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glFrustumxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) -GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed eqn[4]) -GL_ENTRY(void, glGetFixedvOES, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetLightxvOES, GLenum light, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetTexEnvxvOES, GLenum env, GLenum pname, GLfixed *params) -GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params) -GL_ENTRY(void, glLightModelxOES, GLenum pname, GLfixed param) -GL_ENTRY(void, glLightModelxvOES, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glLightxOES, GLenum light, GLenum pname, GLfixed param) -GL_ENTRY(void, glLightxvOES, GLenum light, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glLineWidthxOES, GLfixed width) -GL_ENTRY(void, glLoadMatrixxOES, const GLfixed *m) -GL_ENTRY(void, glMaterialxOES, GLenum face, GLenum pname, GLfixed param) -GL_ENTRY(void, glMaterialxvOES, GLenum face, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m) -GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) -GL_ENTRY(void, glNormal3xOES, GLfixed nx, GLfixed ny, GLfixed nz) -GL_ENTRY(void, glOrthoxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) -GL_ENTRY(void, glPointParameterxOES, GLenum pname, GLfixed param) -GL_ENTRY(void, glPointParameterxvOES, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glPointSizexOES, GLfixed size) -GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units) -GL_ENTRY(void, glRotatexOES, GLfixed angle, GLfixed x, GLfixed y, GLfixed z) -GL_ENTRY(void, glSampleCoveragexOES, GLclampx value, GLboolean invert) -GL_ENTRY(void, glScalexOES, GLfixed x, GLfixed y, GLfixed z) -GL_ENTRY(void, glTexEnvxOES, GLenum target, GLenum pname, GLfixed param) -GL_ENTRY(void, glTexEnvxvOES, GLenum target, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glTexParameterxOES, GLenum target, GLenum pname, GLfixed param) -GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z) -GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer) -GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer) -GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers) -GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers) -GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) -GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params) -GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint framebuffer) -GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer) -GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei n, const GLuint* framebuffers) -GL_ENTRY(void, glGenFramebuffersOES, GLsizei n, GLuint* framebuffers) -GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum target) -GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) -GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) -GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum target, GLenum attachment, GLenum pname, GLint* params) -GL_ENTRY(void, glGenerateMipmapOES, GLenum target) -GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access) -GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target) -GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params) -GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint matrixpaletteindex) -GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void) -GL_ENTRY(void, glMatrixIndexPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) -GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) -GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16]) -GL_ENTRY(void, glDepthRangefOES, GLclampf zNear, GLclampf zFar) -GL_ENTRY(void, glFrustumfOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) -GL_ENTRY(void, glOrthofOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) -GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation) -GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat eqn[4]) -GL_ENTRY(void, glClearDepthfOES, GLclampf depth) -GL_ENTRY(void, glTexGenfOES, GLenum coord, GLenum pname, GLfloat param) -GL_ENTRY(void, glTexGenfvOES, GLenum coord, GLenum pname, const GLfloat *params) -GL_ENTRY(void, glTexGeniOES, GLenum coord, GLenum pname, GLint param) -GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params) -GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param) -GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params) -GL_ENTRY(void, glGetTexGenfvOES, GLenum coord, GLenum pname, GLfloat *params) -GL_ENTRY(void, glGetTexGenivOES, GLenum coord, GLenum pname, GLint *params) -GL_ENTRY(void, glGetTexGenxvOES, GLenum coord, GLenum pname, GLfixed *params) diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h index ac286cb..1fba209 100644 --- a/opengl/libs/egl_impl.h +++ b/opengl/libs/egl_impl.h @@ -23,18 +23,19 @@ #include <EGL/eglext.h> #include <EGL/eglplatform.h> +#include "hooks.h" + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- -struct gl_hooks_t; - struct egl_connection_t { void * dso; - gl_hooks_t * hooks; + gl_hooks_t * hooks[2]; EGLint major; EGLint minor; + egl_t egl; }; EGLAPI EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image); diff --git a/opengl/libs/entries.in b/opengl/libs/entries.in new file mode 100644 index 0000000..bbe3e23 --- /dev/null +++ b/opengl/libs/entries.in @@ -0,0 +1,349 @@ +GL_ENTRY(void, glActiveTexture, GLenum texture) +GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref) +GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref) +GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref) +GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader) +GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor) +GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const char* name) +GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer) +GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer) +GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer) +GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer) +GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer) +GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture) +GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +GL_ENTRY(void, glBlendEquation, GLenum mode ) +GL_ENTRY(void, glBlendEquationOES, GLenum mode) +GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha) +GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha) +GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor) +GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) +GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) +GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target) +GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum target) +GL_ENTRY(void, glClear, GLbitfield mask) +GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +GL_ENTRY(void, glClearColorx, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) +GL_ENTRY(void, glClearColorxOES, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) +GL_ENTRY(void, glClearDepthf, GLclampf depth) +GL_ENTRY(void, glClearDepthfOES, GLclampf depth) +GL_ENTRY(void, glClearDepthx, GLclampx depth) +GL_ENTRY(void, glClearDepthxOES, GLclampx depth) +GL_ENTRY(void, glClearStencil, GLint s) +GL_ENTRY(void, glClientActiveTexture, GLenum texture) +GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation) +GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation) +GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed *equation) +GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed *equation) +GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) +GL_ENTRY(void, glColor4x, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) +GL_ENTRY(void, glColor4xOES, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) +GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glCompileShader, GLuint shader) +GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) +GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) +GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) +GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) +GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(GLuint, glCreateProgram, void) +GL_ENTRY(GLuint, glCreateShader, GLenum type) +GL_ENTRY(void, glCullFace, GLenum mode) +GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint matrixpaletteindex) +GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers) +GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences) +GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers) +GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei n, const GLuint* framebuffers) +GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors) +GL_ENTRY(void, glDeleteProgram, GLuint program) +GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers) +GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers) +GL_ENTRY(void, glDeleteShader, GLuint shader) +GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures) +GL_ENTRY(void, glDepthFunc, GLenum func) +GL_ENTRY(void, glDepthMask, GLboolean flag) +GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar) +GL_ENTRY(void, glDepthRangefOES, GLclampf zNear, GLclampf zFar) +GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar) +GL_ENTRY(void, glDepthRangexOES, GLclampx zNear, GLclampx zFar) +GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader) +GL_ENTRY(void, glDisable, GLenum cap) +GL_ENTRY(void, glDisableClientState, GLenum array) +GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl) +GL_ENTRY(void, glDisableVertexAttribArray, GLuint index) +GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) +GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) +GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) +GL_ENTRY(void, glDrawTexfvOES, const GLfloat *coords) +GL_ENTRY(void, glDrawTexiOES, GLint x, GLint y, GLint z, GLint width, GLint height) +GL_ENTRY(void, glDrawTexivOES, const GLint *coords) +GL_ENTRY(void, glDrawTexsOES, GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) +GL_ENTRY(void, glDrawTexsvOES, const GLshort *coords) +GL_ENTRY(void, glDrawTexxOES, GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) +GL_ENTRY(void, glDrawTexxvOES, const GLfixed *coords) +GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glEnable, GLenum cap) +GL_ENTRY(void, glEnableClientState, GLenum array) +GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl) +GL_ENTRY(void, glEnableVertexAttribArray, GLuint index) +GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor) +GL_ENTRY(void, glFinish, void) +GL_ENTRY(void, glFinishFenceNV, GLuint fence) +GL_ENTRY(void, glFlush, void) +GL_ENTRY(void, glFogf, GLenum pname, GLfloat param) +GL_ENTRY(void, glFogfv, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glFogx, GLenum pname, GLfixed param) +GL_ENTRY(void, glFogxOES, GLenum pname, GLfixed param) +GL_ENTRY(void, glFogxv, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glFogxvOES, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) +GL_ENTRY(void, glFrontFace, GLenum mode) +GL_ENTRY(void, glFrustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glFrustumfOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glFrustumx, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glFrustumxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint *buffers) +GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences) +GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers) +GL_ENTRY(void, glGenFramebuffersOES, GLsizei n, GLuint* framebuffers) +GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors) +GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers) +GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers) +GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures) +GL_ENTRY(void, glGenerateMipmap, GLenum target) +GL_ENTRY(void, glGenerateMipmapOES, GLenum target) +GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) +GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) +GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +GL_ENTRY(int, glGetAttribLocation, GLuint program, const char* name) +GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params) +GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params) +GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params) +GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat eqn[4]) +GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat eqn[4]) +GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed eqn[4]) +GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed eqn[4]) +GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString) +GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls) +GL_ENTRY(GLenum, glGetError, void) +GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params) +GL_ENTRY(void, glGetFixedv, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetFixedvOES, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params) +GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum target, GLenum attachment, GLenum pname, GLint* params) +GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *params) +GL_ENTRY(void, glGetLightfv, GLenum light, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetLightxv, GLenum light, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetLightxvOES, GLenum light, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetMaterialfv, GLenum face, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) +GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, void *data) +GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString) +GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) +GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, char *groupString) +GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups) +GL_ENTRY(void, glGetPointerv, GLenum pname, void **params) +GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) +GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) +GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params) +GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) +GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, char* source) +GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params) +GL_ENTRY(const GLubyte *, glGetString, GLenum name) +GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetTexEnviv, GLenum env, GLenum pname, GLint *params) +GL_ENTRY(void, glGetTexEnvxv, GLenum env, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetTexEnvxvOES, GLenum env, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetTexGenfvOES, GLenum coord, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetTexGenivOES, GLenum coord, GLenum pname, GLint *params) +GL_ENTRY(void, glGetTexGenxvOES, GLenum coord, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params) +GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params) +GL_ENTRY(int, glGetUniformLocation, GLuint program, const char* name) +GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params) +GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params) +GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer) +GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params) +GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params) +GL_ENTRY(void, glHint, GLenum target, GLenum mode) +GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer) +GL_ENTRY(GLboolean, glIsEnabled, GLenum cap) +GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence) +GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer) +GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint framebuffer) +GL_ENTRY(GLboolean, glIsProgram, GLuint program) +GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer) +GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer) +GL_ENTRY(GLboolean, glIsShader, GLuint shader) +GL_ENTRY(GLboolean, glIsTexture, GLuint texture) +GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param) +GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightModelxOES, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightModelxv, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLightModelxvOES, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLightf, GLenum light, GLenum pname, GLfloat param) +GL_ENTRY(void, glLightfv, GLenum light, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glLightx, GLenum light, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightxOES, GLenum light, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightxv, GLenum light, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLightxvOES, GLenum light, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLineWidth, GLfloat width) +GL_ENTRY(void, glLineWidthx, GLfixed width) +GL_ENTRY(void, glLineWidthxOES, GLfixed width) +GL_ENTRY(void, glLinkProgram, GLuint program) +GL_ENTRY(void, glLoadIdentity, void) +GL_ENTRY(void, glLoadMatrixf, const GLfloat *m) +GL_ENTRY(void, glLoadMatrixx, const GLfixed *m) +GL_ENTRY(void, glLoadMatrixxOES, const GLfixed *m) +GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void) +GL_ENTRY(void, glLogicOp, GLenum opcode) +GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access) +GL_ENTRY(void, glMaterialf, GLenum face, GLenum pname, GLfloat param) +GL_ENTRY(void, glMaterialfv, GLenum face, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glMaterialx, GLenum face, GLenum pname, GLfixed param) +GL_ENTRY(void, glMaterialxOES, GLenum face, GLenum pname, GLfixed param) +GL_ENTRY(void, glMaterialxv, GLenum face, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glMaterialxvOES, GLenum face, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glMatrixIndexPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glMatrixMode, GLenum mode) +GL_ENTRY(void, glMultMatrixf, const GLfloat *m) +GL_ENTRY(void, glMultMatrixx, const GLfixed *m) +GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m) +GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) +GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) +GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) +GL_ENTRY(void, glNormal3f, GLfloat nx, GLfloat ny, GLfloat nz) +GL_ENTRY(void, glNormal3x, GLfixed nx, GLfixed ny, GLfixed nz) +GL_ENTRY(void, glNormal3xOES, GLfixed nx, GLfixed ny, GLfixed nz) +GL_ENTRY(void, glNormalPointer, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glOrthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glOrthofOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glOrthox, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glOrthoxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param) +GL_ENTRY(void, glPointParameterf, GLenum pname, GLfloat param) +GL_ENTRY(void, glPointParameterfv, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glPointParameterx, GLenum pname, GLfixed param) +GL_ENTRY(void, glPointParameterxOES, GLenum pname, GLfixed param) +GL_ENTRY(void, glPointParameterxv, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glPointParameterxvOES, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glPointSize, GLfloat size) +GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glPointSizex, GLfixed size) +GL_ENTRY(void, glPointSizexOES, GLfixed size) +GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units) +GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units) +GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units) +GL_ENTRY(void, glPopMatrix, void) +GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const void *binary, GLint length) +GL_ENTRY(void, glPushMatrix, void) +GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16]) +GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) +GL_ENTRY(void, glReleaseShaderCompiler, void) +GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glRotatexOES, GLfixed angle, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert) +GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert) +GL_ENTRY(void, glSampleCoveragexOES, GLclampx value, GLboolean invert) +GL_ENTRY(void, glScalef, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glScalex, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glScalexOES, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) +GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition) +GL_ENTRY(void, glShadeModel, GLenum mode) +GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) +GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const char** string, const GLint* length) +GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) +GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask) +GL_ENTRY(void, glStencilMask, GLuint mask) +GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask) +GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) +GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence) +GL_ENTRY(void, glTexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glTexEnvf, GLenum target, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexEnvfv, GLenum target, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glTexEnvi, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glTexEnviv, GLenum target, GLenum pname, const GLint *params) +GL_ENTRY(void, glTexEnvx, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexEnvxOES, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexEnvxv, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexEnvxvOES, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexGenfOES, GLenum coord, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexGenfvOES, GLenum coord, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glTexGeniOES, GLenum coord, GLenum pname, GLint param) +GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params) +GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) +GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint *params) +GL_ENTRY(void, glTexParameterx, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexParameterxOES, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) +GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glUniform1f, GLint location, GLfloat x) +GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform1i, GLint location, GLint x) +GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform2f, GLint location, GLfloat x, GLfloat y) +GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform2i, GLint location, GLint x, GLint y) +GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform3f, GLint location, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform3i, GLint location, GLint x, GLint y, GLint z) +GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform4f, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform4i, GLint location, GLint x, GLint y, GLint z, GLint w) +GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target) +GL_ENTRY(void, glUseProgram, GLuint program) +GL_ENTRY(void, glValidateProgram, GLuint program) +GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x) +GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y) +GL_ENTRY(void, glVertexAttrib2fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib3f, GLuint indx, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) +GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h index 8c0357e..f47f093 100644 --- a/opengl/libs/hooks.h +++ b/opengl/libs/hooks.h @@ -60,11 +60,14 @@ const unsigned int NUM_DISPLAYS = 1; enum { IMPL_HARDWARE = 0, IMPL_SOFTWARE, - IMPL_NUM_DRIVERS_IMPLEMENTATIONS, - IMPL_NO_CONTEXT = IMPL_NUM_DRIVERS_IMPLEMENTATIONS, IMPL_NUM_IMPLEMENTATIONS }; +enum { + GLESv1_INDEX = 0, + GLESv2_INDEX = 1, +}; + // ---------------------------------------------------------------------------- // GL / EGL hooks @@ -74,18 +77,14 @@ enum { #define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__); #define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__); +struct egl_t { + #include "EGL/egl_entries.in" +}; + struct gl_hooks_t { struct gl_t { - #include "GLES_CM/gl_entries.in" - #include "GLES_CM/glext_entries.in" + #include "entries.in" } gl; - struct gl2_t { - #include "GLES2/gl2_entries.in" - #include "GLES2/gl2ext_entries.in" - } gl2; - struct egl_t { - #include "EGL/egl_entries.in" - } egl; struct gl_ext_t { void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void); } ext; @@ -96,12 +95,12 @@ struct gl_hooks_t { // ---------------------------------------------------------------------------- -extern gl_hooks_t gHooks[IMPL_NUM_IMPLEMENTATIONS]; +extern gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS]; +extern gl_hooks_t gHooksNoContext; extern pthread_key_t gGLWrapperKey; extern "C" void gl_unimplemented(); extern char const * const gl_names[]; -extern char const * const gl2_names[]; extern char const * const egl_names[]; // ---------------------------------------------------------------------------- @@ -125,7 +124,7 @@ static gl_hooks_t const* getGlThreadSpecific() { gl_hooks_t const * volatile * tls_hooks = get_tls_hooks(); gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API]; if (hooks) return hooks; - return &gHooks[IMPL_NO_CONTEXT]; + return &gHooksNoContext; } #else @@ -137,7 +136,7 @@ static inline void setGlThreadSpecific(gl_hooks_t const *value) { static gl_hooks_t const* getGlThreadSpecific() { gl_hooks_t const* hooks = static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey)); if (hooks) return hooks; - return &gHooks[IMPL_NO_CONTEXT]; + return &gHooksNoContext; } #endif diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles index 4f8eda4..120cb4b 100755 --- a/opengl/libs/tools/genfiles +++ b/opengl/libs/tools/genfiles @@ -14,14 +14,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -./glapigen ../../include/GLES/gl.h > ../GLES_CM/gl_api.in -./glentrygen ../../include/GLES/gl.h > ../GLES_CM/gl_entries.in +./glapigen ../../include/GLES/gl.h > ../GLES_CM/gl_api.in +./glapigen ../../include/GLES/glext.h > ../GLES_CM/glext_api.in +./glapigen ../../include/GLES2/gl2.h > ../GLES2/gl2_api.in +./glapigen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_api.in -./glapigen ../../include/GLES/glext.h > ../GLES_CM/glext_api.in -./glentrygen ../../include/GLES/glext.h > ../GLES_CM/glext_entries.in +./glentrygen ../../include/GLES/gl.h > /tmp/gl_entries.in +./glentrygen ../../include/GLES/glext.h > /tmp/glext_entries.in +./glentrygen ../../include/GLES2/gl2.h > /tmp/gl2_entries.in +./glentrygen ../../include/GLES2/gl2ext.h > /tmp/gl2ext_entries.in -./glapigen ../../include/GLES2/gl2.h > ../GLES2/gl2_api.in -./glentrygen ../../include/GLES2/gl2.h > ../GLES2/gl2_entries.in - -./glapigen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_api.in -./glentrygen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_entries.in +cat /tmp/gl_entries.in \ + /tmp/glext_entries.in \ + /tmp/gl2_entries.in \ + /tmp/gl2ext_entries.in \ + | sort -t, -k2 \ + | awk -F, '!_[$2]++' \ + > ../entries.in diff --git a/opengl/tests/linetex/Android.mk b/opengl/tests/linetex/Android.mk new file mode 100644 index 0000000..6ff248d --- /dev/null +++ b/opengl/tests/linetex/Android.mk @@ -0,0 +1,17 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + linetex.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv1_CM \ + libui + +LOCAL_MODULE:= test-opengl-linetex + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/linetex/linetex.cpp b/opengl/tests/linetex/linetex.cpp new file mode 100644 index 0000000..6842940 --- /dev/null +++ b/opengl/tests/linetex/linetex.cpp @@ -0,0 +1,116 @@ +/* +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#define LOG_TAG "fillrate" + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#include <EGL/egl.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include <utils/StopWatch.h> +#include <ui/FramebufferNativeWindow.h> +#include <ui/EGLUtils.h> + +using namespace android; + +int main(int argc, char** argv) +{ + EGLint configAttribs[] = { + EGL_DEPTH_SIZE, 0, + EGL_NONE + }; + + EGLint majorVersion; + EGLint minorVersion; + EGLContext context; + EGLConfig config; + EGLSurface surface; + EGLint w, h; + EGLDisplay dpy; + + EGLNativeWindowType window = android_createDisplaySurface(); + + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglInitialize(dpy, &majorVersion, &minorVersion); + + status_t err = EGLUtils::selectConfigForNativeWindow( + dpy, configAttribs, window, &config); + if (err) { + fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n"); + return 0; + } + + surface = eglCreateWindowSurface(dpy, config, window, NULL); + context = eglCreateContext(dpy, config, NULL, NULL); + eglMakeCurrent(dpy, surface, surface, context); + eglQuerySurface(dpy, surface, EGL_WIDTH, &w); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); + + printf("w=%d, h=%d\n", w, h); + + glBindTexture(GL_TEXTURE_2D, 0); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glDisable(GL_DITHER); + glDisable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + + + // default pack-alignment is 4 + const uint16_t t16[64] = { 0xFFFF, 0, 0xF800, 0, 0x07E0, 0, 0x001F, 0 }; + + const GLfloat vertices[4][2] = { + { w/2, 0 }, + { w/2, h } + }; + + const GLfloat texCoords[4][2] = { + { 0, 0 }, + { 1, 1 } + }; + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 4, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t16); + + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, w, 0, h, 0, 1); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_LINES, 0, 2); + eglSwapBuffers(dpy, surface); + + usleep(5*1000000); + + eglTerminate(dpy); + + return 0; +} diff --git a/opengl/tools/glgen/specs/gles11/checks.spec b/opengl/tools/glgen/specs/gles11/checks.spec index e31a2ce..1468ab9 100644 --- a/opengl/tools/glgen/specs/gles11/checks.spec +++ b/opengl/tools/glgen/specs/gles11/checks.spec @@ -1,61 +1,62 @@ -glClipPlanef check eqn 4
-glClipPlanex check eqn 4
-glGetClipPlanefOES check eqn 4
-glGetClipPlanexOES check eqn 4
-glDeleteBuffers check buffers n
-glDeleteTextures check textures n
-glDrawElements check_AIOOBE indices count
-glFog ifcheck params 1 pname GL_FOG_MODE,GL_FOG_DENSITY,GL_FOG_START,GL_FOG_END ifcheck params 4 pname GL_FOG_COLOR
-glGenBuffers check buffers n
-glGenTextures check textures n
-glGetClipPlane check eqn 4
-glGetIntegerv ifcheck params 1 pname GL_ALPHA_BITS,GL_ALPHA_TEST_FUNC,GL_ALPHA_TEST_REF,GL_BLEND_DST,GL_BLUE_BITS,GL_COLOR_ARRAY_BUFFER_BINDING,GL_COLOR_ARRAY_SIZE,GL_COLOR_ARRAY_STRIDE,GL_COLOR_ARRAY_TYPE,GL_CULL_FACE,GL_DEPTH_BITS,GL_DEPTH_CLEAR_VALUE,GL_DEPTH_FUNC,GL_DEPTH_WRITEMASK,GL_FOG_DENSITY,GL_FOG_END,GL_FOG_MODE,GL_FOG_START,GL_FRONT_FACE,GL_GREEN_BITS,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES,GL_LIGHT_MODEL_COLOR_CONTROL,GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE,GL_LINE_SMOOTH_HINT,GL_LINE_WIDTH,GL_LOGIC_OP_MODE,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES,GL_MATRIX_INDEX_ARRAY_SIZE_OES,GL_MATRIX_INDEX_ARRAY_STRIDE_OES,GL_MATRIX_INDEX_ARRAY_TYPE_OES,GL_MATRIX_MODE,GL_MAX_CLIP_PLANES,GL_MAX_ELEMENTS_INDICES,GL_MAX_ELEMENTS_VERTICES,GL_MAX_LIGHTS,GL_MAX_MODELVIEW_STACK_DEPTH,GL_MAX_PALETTE_MATRICES_OES,GL_MAX_PROJECTION_STACK_DEPTH,GL_MAX_TEXTURE_SIZE,GL_MAX_TEXTURE_STACK_DEPTH,GL_MAX_TEXTURE_UNITS,GL_MAX_VERTEX_UNITS_OES,GL_MODELVIEW_STACK_DEPTH,GL_NORMAL_ARRAY_BUFFER_BINDING,GL_NORMAL_ARRAY_STRIDE,GL_NORMAL_ARRAY_TYPE,GL_NUM_COMPRESSED_TEXTURE_FORMATS,GL_PACK_ALIGNMENT,GL_PERSPECTIVE_CORRECTION_HINT,GL_POINT_SIZE,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES,GL_POINT_SIZE_ARRAY_STRIDE_OES,GL_POINT_SIZE_ARRAY_TYPE_OES,GL_POINT_SMOOTH_HINT,GL_POLYGON_OFFSET_FACTOR,GL_POLYGON_OFFSET_UNITS,GL_PROJECTION_STACK_DEPTH,GL_RED_BITS,GL_SHADE_MODEL,GL_STENCIL_BITS,GL_STENCIL_CLEAR_VALUE,GL_STENCIL_FAIL,GL_STENCIL_FUNC,GL_STENCIL_PASS_DEPTH_FAIL,GL_STENCIL_PASS_DEPTH_PASS,GL_STENCIL_REF,GL_STENCIL_VALUE_MASK,GL_STENCIL_WRITEMASK,GL_SUBPIXEL_BITS,GL_TEXTURE_BINDING_2D,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING,GL_TEXTURE_COORD_ARRAY_SIZE,GL_TEXTURE_COORD_ARRAY_STRIDE,GL_TEXTURE_COORD_ARRAY_TYPE,GL_TEXTURE_STACK_DEPTH,GL_UNPACK_ALIGNMENT,GL_VERTEX_ARRAY_BUFFER_BINDING,GL_VERTEX_ARRAY_SIZE,GL_VERTEX_ARRAY_STRIDE,GL_VERTEX_ARRAY_TYPE,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES,GL_WEIGHT_ARRAY_SIZE_OES,GL_WEIGHT_ARRAY_STRIDE_OES,GL_WEIGHT_ARRAY_TYPE_OES ifcheck params 2 pname GL_ALIASED_POINT_SIZE_RANGE,GL_ALIASED_LINE_WIDTH_RANGE,GL_DEPTH_RANGE,GL_MAX_VIEWPORT_DIMS,GL_SMOOTH_LINE_WIDTH_RANGE,GL_SMOOTH_POINT_SIZE_RANGE ifcheck params 4 pname GL_COLOR_CLEAR_VALUE,GL_COLOR_WRITEMASK,GL_FOG_COLOR,GL_LIGHT_MODEL_AMBIENT,GL_SCISSOR_BOX,GL_VIEWPORT ifcheck params 16 pname GL_MODELVIEW_MATRIX,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES,GL_PROJECTION_MATRIX,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES,GL_TEXTURE_MATRIX,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES ifcheck params getNumCompressedTextureFormats() pname GL_COMPRESSED_TEXTURE_FORMATS
-glGetLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION
-glGetMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE
-glGetTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR
-glGetTexParameter check params 1
-glLightModel ifcheck params 1 pname GL_LIGHT_MODEL_TWO_SIDE ifcheck params 4 pname GL_LIGHT_MODEL_AMBIENT
-glLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION
-glLoadMatrix check m 16
-glMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE
-glMultMatrix check m 16
-glPointParameter check params 1
-glTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR
-glTexImage2D nullAllowed
-glTexSubImage2D nullAllowed
-glBufferData nullAllowed
-glTexParameter check params 1
-glQueryMatrixxOES check mantissa 16 check exponent 16 return -1
-glDrawTexfvOES check coords 5
-glDrawTexivOES check coords 5
-glDrawTexsvOES check coords 5
-glDrawTexxvOES check coords 5
-glBindFramebufferOES unsupported
-glBindRenderbufferOES unsupported
-glBlendEquation unsupported
-glBlendEquationSeparate unsupported
-glBlendFuncSeparate unsupported
-glCheckFramebufferStatusOES unsupported return 0
-glCurrentPaletteMatrixOES unsupported
-glDeleteFramebuffersOES unsupported
-glDeleteRenderbuffersOES unsupported
-glFramebufferRenderbufferOES unsupported
-glFramebufferStorageOES unsupported
-glFramebufferTexture2DOES unsupported
-glGenFramebuffersOES unsupported
-glGenRenderbuffersOES unsupported
-glGenerateMipmapOES unsupported
-glGetBufferParameter unsupported
-glGetFramebufferAttachmentParameterivOES unsupported
-glGetRenderbufferParameterivOES unsupported
-glGetTexGen unsupported
-glIsFramebufferOES unsupported return JNI_FALSE
-glIsRenderbufferOES unsupported return JNI_FALSE
-glLoadPaletteFromModelViewMatrixOES unsupported
-glMatrixIndexPointerOES unsupported
-glRenderbufferStorageOES unsupported return false
-glTexGen unsupported
-glTexGenf unsupported
-glTexGeni unsupported
-glTexGenx unsupported
-glWeightPointerOES unsupported
+glClipPlanef check eqn 4 +glClipPlanex check eqn 4 +glGetClipPlanefOES check eqn 4 +glGetClipPlanexOES check eqn 4 +glDeleteBuffers check buffers n +glDeleteTextures check textures n +glDrawElements check_AIOOBE indices count +glFog ifcheck params 1 pname GL_FOG_MODE,GL_FOG_DENSITY,GL_FOG_START,GL_FOG_END ifcheck params 4 pname GL_FOG_COLOR +glGenBuffers check buffers n +glGenTextures check textures n +glGetClipPlane check eqn 4 +glGetIntegerv ifcheck params 1 pname GL_ALPHA_BITS,GL_ALPHA_TEST_FUNC,GL_ALPHA_TEST_REF,GL_BLEND_DST,GL_BLUE_BITS,GL_COLOR_ARRAY_BUFFER_BINDING,GL_COLOR_ARRAY_SIZE,GL_COLOR_ARRAY_STRIDE,GL_COLOR_ARRAY_TYPE,GL_CULL_FACE,GL_DEPTH_BITS,GL_DEPTH_CLEAR_VALUE,GL_DEPTH_FUNC,GL_DEPTH_WRITEMASK,GL_FOG_DENSITY,GL_FOG_END,GL_FOG_MODE,GL_FOG_START,GL_FRONT_FACE,GL_GREEN_BITS,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES,GL_LIGHT_MODEL_COLOR_CONTROL,GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE,GL_LINE_SMOOTH_HINT,GL_LINE_WIDTH,GL_LOGIC_OP_MODE,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES,GL_MATRIX_INDEX_ARRAY_SIZE_OES,GL_MATRIX_INDEX_ARRAY_STRIDE_OES,GL_MATRIX_INDEX_ARRAY_TYPE_OES,GL_MATRIX_MODE,GL_MAX_CLIP_PLANES,GL_MAX_ELEMENTS_INDICES,GL_MAX_ELEMENTS_VERTICES,GL_MAX_LIGHTS,GL_MAX_MODELVIEW_STACK_DEPTH,GL_MAX_PALETTE_MATRICES_OES,GL_MAX_PROJECTION_STACK_DEPTH,GL_MAX_TEXTURE_SIZE,GL_MAX_TEXTURE_STACK_DEPTH,GL_MAX_TEXTURE_UNITS,GL_MAX_VERTEX_UNITS_OES,GL_MODELVIEW_STACK_DEPTH,GL_NORMAL_ARRAY_BUFFER_BINDING,GL_NORMAL_ARRAY_STRIDE,GL_NORMAL_ARRAY_TYPE,GL_NUM_COMPRESSED_TEXTURE_FORMATS,GL_PACK_ALIGNMENT,GL_PERSPECTIVE_CORRECTION_HINT,GL_POINT_SIZE,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES,GL_POINT_SIZE_ARRAY_STRIDE_OES,GL_POINT_SIZE_ARRAY_TYPE_OES,GL_POINT_SMOOTH_HINT,GL_POLYGON_OFFSET_FACTOR,GL_POLYGON_OFFSET_UNITS,GL_PROJECTION_STACK_DEPTH,GL_RED_BITS,GL_SHADE_MODEL,GL_STENCIL_BITS,GL_STENCIL_CLEAR_VALUE,GL_STENCIL_FAIL,GL_STENCIL_FUNC,GL_STENCIL_PASS_DEPTH_FAIL,GL_STENCIL_PASS_DEPTH_PASS,GL_STENCIL_REF,GL_STENCIL_VALUE_MASK,GL_STENCIL_WRITEMASK,GL_SUBPIXEL_BITS,GL_TEXTURE_BINDING_2D,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING,GL_TEXTURE_COORD_ARRAY_SIZE,GL_TEXTURE_COORD_ARRAY_STRIDE,GL_TEXTURE_COORD_ARRAY_TYPE,GL_TEXTURE_STACK_DEPTH,GL_UNPACK_ALIGNMENT,GL_VERTEX_ARRAY_BUFFER_BINDING,GL_VERTEX_ARRAY_SIZE,GL_VERTEX_ARRAY_STRIDE,GL_VERTEX_ARRAY_TYPE,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES,GL_WEIGHT_ARRAY_SIZE_OES,GL_WEIGHT_ARRAY_STRIDE_OES,GL_WEIGHT_ARRAY_TYPE_OES ifcheck params 2 pname GL_ALIASED_POINT_SIZE_RANGE,GL_ALIASED_LINE_WIDTH_RANGE,GL_DEPTH_RANGE,GL_MAX_VIEWPORT_DIMS,GL_SMOOTH_LINE_WIDTH_RANGE,GL_SMOOTH_POINT_SIZE_RANGE ifcheck params 4 pname GL_COLOR_CLEAR_VALUE,GL_COLOR_WRITEMASK,GL_FOG_COLOR,GL_LIGHT_MODEL_AMBIENT,GL_SCISSOR_BOX,GL_VIEWPORT ifcheck params 16 pname GL_MODELVIEW_MATRIX,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES,GL_PROJECTION_MATRIX,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES,GL_TEXTURE_MATRIX,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES ifcheck params getNumCompressedTextureFormats() pname GL_COMPRESSED_TEXTURE_FORMATS +glGetLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION +glGetMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE +glGetTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR +glGetTexParameter check params 1 +glLightModel ifcheck params 1 pname GL_LIGHT_MODEL_TWO_SIDE ifcheck params 4 pname GL_LIGHT_MODEL_AMBIENT +glLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION +glLoadMatrix check m 16 +glMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE +glMultMatrix check m 16 +glPointParameter check params 1 +glTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR +glTexImage2D nullAllowed +glTexSubImage2D nullAllowed +glBufferData nullAllowed check data size +glBufferSubData check data size +glTexParameter check params 1 +glQueryMatrixxOES check mantissa 16 check exponent 16 return -1 +glDrawTexfvOES check coords 5 +glDrawTexivOES check coords 5 +glDrawTexsvOES check coords 5 +glDrawTexxvOES check coords 5 +glBindFramebufferOES unsupported +glBindRenderbufferOES unsupported +glBlendEquation unsupported +glBlendEquationSeparate unsupported +glBlendFuncSeparate unsupported +glCheckFramebufferStatusOES unsupported return 0 +glCurrentPaletteMatrixOES unsupported +glDeleteFramebuffersOES unsupported +glDeleteRenderbuffersOES unsupported +glFramebufferRenderbufferOES unsupported +glFramebufferStorageOES unsupported +glFramebufferTexture2DOES unsupported +glGenFramebuffersOES unsupported +glGenRenderbuffersOES unsupported +glGenerateMipmapOES unsupported +glGetBufferParameter unsupported +glGetFramebufferAttachmentParameterivOES unsupported +glGetRenderbufferParameterivOES unsupported +glGetTexGen unsupported +glIsFramebufferOES unsupported return JNI_FALSE +glIsRenderbufferOES unsupported return JNI_FALSE +glLoadPaletteFromModelViewMatrixOES unsupported +glMatrixIndexPointerOES unsupported +glRenderbufferStorageOES unsupported return false +glTexGen unsupported +glTexGenf unsupported +glTexGeni unsupported +glTexGenx unsupported +glWeightPointerOES unsupported diff --git a/opengl/tools/glgen/specs/jsr239/glspec-checks b/opengl/tools/glgen/specs/jsr239/glspec-checks index 55840fa..063cdc7 100644 --- a/opengl/tools/glgen/specs/jsr239/glspec-checks +++ b/opengl/tools/glgen/specs/jsr239/glspec-checks @@ -1,59 +1,60 @@ -glClipPlanef check equation 4
-glClipPlanex check equation 4
-glDeleteBuffers check buffers n
-glDeleteTextures check textures n
-glDrawElements check_AIOOBE indices count
-glFog ifcheck params 1 pname GL_FOG_MODE,GL_FOG_DENSITY,GL_FOG_START,GL_FOG_END ifcheck params 4 pname GL_FOG_COLOR
-glGenBuffers check buffers n
-glGenTextures check textures n
-glGetClipPlane check eqn 4
-glGetIntegerv ifcheck params 1 pname GL_ALPHA_BITS,GL_ALPHA_TEST_FUNC,GL_ALPHA_TEST_REF,GL_BLEND_DST,GL_BLUE_BITS,GL_COLOR_ARRAY_BUFFER_BINDING,GL_COLOR_ARRAY_SIZE,GL_COLOR_ARRAY_STRIDE,GL_COLOR_ARRAY_TYPE,GL_CULL_FACE,GL_DEPTH_BITS,GL_DEPTH_CLEAR_VALUE,GL_DEPTH_FUNC,GL_DEPTH_WRITEMASK,GL_FOG_DENSITY,GL_FOG_END,GL_FOG_MODE,GL_FOG_START,GL_FRONT_FACE,GL_GREEN_BITS,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES,GL_LIGHT_MODEL_COLOR_CONTROL,GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE,GL_LINE_SMOOTH_HINT,GL_LINE_WIDTH,GL_LOGIC_OP_MODE,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES,GL_MATRIX_INDEX_ARRAY_SIZE_OES,GL_MATRIX_INDEX_ARRAY_STRIDE_OES,GL_MATRIX_INDEX_ARRAY_TYPE_OES,GL_MATRIX_MODE,GL_MAX_CLIP_PLANES,GL_MAX_ELEMENTS_INDICES,GL_MAX_ELEMENTS_VERTICES,GL_MAX_LIGHTS,GL_MAX_MODELVIEW_STACK_DEPTH,GL_MAX_PALETTE_MATRICES_OES,GL_MAX_PROJECTION_STACK_DEPTH,GL_MAX_TEXTURE_SIZE,GL_MAX_TEXTURE_STACK_DEPTH,GL_MAX_TEXTURE_UNITS,GL_MAX_VERTEX_UNITS_OES,GL_MODELVIEW_STACK_DEPTH,GL_NORMAL_ARRAY_BUFFER_BINDING,GL_NORMAL_ARRAY_STRIDE,GL_NORMAL_ARRAY_TYPE,GL_NUM_COMPRESSED_TEXTURE_FORMATS,GL_PACK_ALIGNMENT,GL_PERSPECTIVE_CORRECTION_HINT,GL_POINT_SIZE,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES,GL_POINT_SIZE_ARRAY_STRIDE_OES,GL_POINT_SIZE_ARRAY_TYPE_OES,GL_POINT_SMOOTH_HINT,GL_POLYGON_OFFSET_FACTOR,GL_POLYGON_OFFSET_UNITS,GL_PROJECTION_STACK_DEPTH,GL_RED_BITS,GL_SHADE_MODEL,GL_STENCIL_BITS,GL_STENCIL_CLEAR_VALUE,GL_STENCIL_FAIL,GL_STENCIL_FUNC,GL_STENCIL_PASS_DEPTH_FAIL,GL_STENCIL_PASS_DEPTH_PASS,GL_STENCIL_REF,GL_STENCIL_VALUE_MASK,GL_STENCIL_WRITEMASK,GL_SUBPIXEL_BITS,GL_TEXTURE_BINDING_2D,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING,GL_TEXTURE_COORD_ARRAY_SIZE,GL_TEXTURE_COORD_ARRAY_STRIDE,GL_TEXTURE_COORD_ARRAY_TYPE,GL_TEXTURE_STACK_DEPTH,GL_UNPACK_ALIGNMENT,GL_VERTEX_ARRAY_BUFFER_BINDING,GL_VERTEX_ARRAY_SIZE,GL_VERTEX_ARRAY_STRIDE,GL_VERTEX_ARRAY_TYPE,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES,GL_WEIGHT_ARRAY_SIZE_OES,GL_WEIGHT_ARRAY_STRIDE_OES,GL_WEIGHT_ARRAY_TYPE_OES ifcheck params 2 pname GL_ALIASED_POINT_SIZE_RANGE,GL_ALIASED_LINE_WIDTH_RANGE,GL_DEPTH_RANGE,GL_MAX_VIEWPORT_DIMS,GL_SMOOTH_LINE_WIDTH_RANGE,GL_SMOOTH_POINT_SIZE_RANGE ifcheck params 4 pname GL_COLOR_CLEAR_VALUE,GL_COLOR_WRITEMASK,GL_FOG_COLOR,GL_LIGHT_MODEL_AMBIENT,GL_SCISSOR_BOX,GL_VIEWPORT ifcheck params 16 pname GL_MODELVIEW_MATRIX,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES,GL_PROJECTION_MATRIX,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES,GL_TEXTURE_MATRIX,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES ifcheck params getNumCompressedTextureFormats() pname GL_COMPRESSED_TEXTURE_FORMATS
-glGetLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION
-glGetMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE
-glGetTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR
-glGetTexParameter check params 1
-glLightModel ifcheck params 1 pname GL_LIGHT_MODEL_TWO_SIDE ifcheck params 4 pname GL_LIGHT_MODEL_AMBIENT
-glLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION
-glLoadMatrix check m 16
-glMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE
-glMultMatrix check m 16
-glPointParameter check params 1
-glTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR
-glTexImage2D nullAllowed
-glTexSubImage2D nullAllowed
-glBufferData nullAllowed
-glTexParameter check params 1
-glQueryMatrixxOES check mantissa 16 check exponent 16 return -1
-glDrawTexfvOES check coords 5
-glDrawTexivOES check coords 5
-glDrawTexsvOES check coords 5
-glDrawTexxvOES check coords 5
-glBindFramebufferOES unsupported
-glBindRenderbufferOES unsupported
-glBlendEquation unsupported
-glBlendEquationSeparate unsupported
-glBlendFuncSeparate unsupported
-glCheckFramebufferStatusOES unsupported return 0
-glCurrentPaletteMatrixOES unsupported
-glDeleteFramebuffersOES unsupported
-glDeleteRenderbuffersOES unsupported
-glFramebufferRenderbufferOES unsupported
-glFramebufferStorageOES unsupported
-glFramebufferTexture2DOES unsupported
-glGenFramebuffersOES unsupported
-glGenRenderbuffersOES unsupported
-glGenerateMipmapOES unsupported
-glGetBufferParameter unsupported
-glGetFramebufferAttachmentParameterivOES unsupported
-glGetRenderbufferParameterivOES unsupported
-glGetTexGen unsupported
-glIsFramebufferOES unsupported return JNI_FALSE
-glIsRenderbufferOES unsupported return JNI_FALSE
-glLoadPaletteFromModelViewMatrixOES unsupported
-glMatrixIndexPointerOES unsupported
-glRenderbufferStorageOES unsupported return false
-glTexGen unsupported
-glTexGenf unsupported
-glTexGeni unsupported
-glTexGenx unsupported
-glWeightPointerOES unsupported
+glClipPlanef check equation 4 +glClipPlanex check equation 4 +glDeleteBuffers check buffers n +glDeleteTextures check textures n +glDrawElements check_AIOOBE indices count +glFog ifcheck params 1 pname GL_FOG_MODE,GL_FOG_DENSITY,GL_FOG_START,GL_FOG_END ifcheck params 4 pname GL_FOG_COLOR +glGenBuffers check buffers n +glGenTextures check textures n +glGetClipPlane check eqn 4 +glGetIntegerv ifcheck params 1 pname GL_ALPHA_BITS,GL_ALPHA_TEST_FUNC,GL_ALPHA_TEST_REF,GL_BLEND_DST,GL_BLUE_BITS,GL_COLOR_ARRAY_BUFFER_BINDING,GL_COLOR_ARRAY_SIZE,GL_COLOR_ARRAY_STRIDE,GL_COLOR_ARRAY_TYPE,GL_CULL_FACE,GL_DEPTH_BITS,GL_DEPTH_CLEAR_VALUE,GL_DEPTH_FUNC,GL_DEPTH_WRITEMASK,GL_FOG_DENSITY,GL_FOG_END,GL_FOG_MODE,GL_FOG_START,GL_FRONT_FACE,GL_GREEN_BITS,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES,GL_LIGHT_MODEL_COLOR_CONTROL,GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE,GL_LINE_SMOOTH_HINT,GL_LINE_WIDTH,GL_LOGIC_OP_MODE,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES,GL_MATRIX_INDEX_ARRAY_SIZE_OES,GL_MATRIX_INDEX_ARRAY_STRIDE_OES,GL_MATRIX_INDEX_ARRAY_TYPE_OES,GL_MATRIX_MODE,GL_MAX_CLIP_PLANES,GL_MAX_ELEMENTS_INDICES,GL_MAX_ELEMENTS_VERTICES,GL_MAX_LIGHTS,GL_MAX_MODELVIEW_STACK_DEPTH,GL_MAX_PALETTE_MATRICES_OES,GL_MAX_PROJECTION_STACK_DEPTH,GL_MAX_TEXTURE_SIZE,GL_MAX_TEXTURE_STACK_DEPTH,GL_MAX_TEXTURE_UNITS,GL_MAX_VERTEX_UNITS_OES,GL_MODELVIEW_STACK_DEPTH,GL_NORMAL_ARRAY_BUFFER_BINDING,GL_NORMAL_ARRAY_STRIDE,GL_NORMAL_ARRAY_TYPE,GL_NUM_COMPRESSED_TEXTURE_FORMATS,GL_PACK_ALIGNMENT,GL_PERSPECTIVE_CORRECTION_HINT,GL_POINT_SIZE,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES,GL_POINT_SIZE_ARRAY_STRIDE_OES,GL_POINT_SIZE_ARRAY_TYPE_OES,GL_POINT_SMOOTH_HINT,GL_POLYGON_OFFSET_FACTOR,GL_POLYGON_OFFSET_UNITS,GL_PROJECTION_STACK_DEPTH,GL_RED_BITS,GL_SHADE_MODEL,GL_STENCIL_BITS,GL_STENCIL_CLEAR_VALUE,GL_STENCIL_FAIL,GL_STENCIL_FUNC,GL_STENCIL_PASS_DEPTH_FAIL,GL_STENCIL_PASS_DEPTH_PASS,GL_STENCIL_REF,GL_STENCIL_VALUE_MASK,GL_STENCIL_WRITEMASK,GL_SUBPIXEL_BITS,GL_TEXTURE_BINDING_2D,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING,GL_TEXTURE_COORD_ARRAY_SIZE,GL_TEXTURE_COORD_ARRAY_STRIDE,GL_TEXTURE_COORD_ARRAY_TYPE,GL_TEXTURE_STACK_DEPTH,GL_UNPACK_ALIGNMENT,GL_VERTEX_ARRAY_BUFFER_BINDING,GL_VERTEX_ARRAY_SIZE,GL_VERTEX_ARRAY_STRIDE,GL_VERTEX_ARRAY_TYPE,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES,GL_WEIGHT_ARRAY_SIZE_OES,GL_WEIGHT_ARRAY_STRIDE_OES,GL_WEIGHT_ARRAY_TYPE_OES ifcheck params 2 pname GL_ALIASED_POINT_SIZE_RANGE,GL_ALIASED_LINE_WIDTH_RANGE,GL_DEPTH_RANGE,GL_MAX_VIEWPORT_DIMS,GL_SMOOTH_LINE_WIDTH_RANGE,GL_SMOOTH_POINT_SIZE_RANGE ifcheck params 4 pname GL_COLOR_CLEAR_VALUE,GL_COLOR_WRITEMASK,GL_FOG_COLOR,GL_LIGHT_MODEL_AMBIENT,GL_SCISSOR_BOX,GL_VIEWPORT ifcheck params 16 pname GL_MODELVIEW_MATRIX,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES,GL_PROJECTION_MATRIX,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES,GL_TEXTURE_MATRIX,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES ifcheck params getNumCompressedTextureFormats() pname GL_COMPRESSED_TEXTURE_FORMATS +glGetLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION +glGetMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE +glGetTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR +glGetTexParameter check params 1 +glLightModel ifcheck params 1 pname GL_LIGHT_MODEL_TWO_SIDE ifcheck params 4 pname GL_LIGHT_MODEL_AMBIENT +glLight ifcheck params 1 pname GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION ifcheck params 3 pname GL_SPOT_DIRECTION ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION +glLoadMatrix check m 16 +glMaterial ifcheck params 1 pname GL_SHININESS ifcheck params 4 pname GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,GL_EMISSION,GL_AMBIENT_AND_DIFFUSE +glMultMatrix check m 16 +glPointParameter check params 1 +glTexEnv ifcheck params 1 pname GL_TEXTURE_ENV_MODE,GL_COMBINE_RGB,GL_COMBINE_ALPHA ifcheck params 4 pname GL_TEXTURE_ENV_COLOR +glTexImage2D nullAllowed +glTexSubImage2D nullAllowed +glBufferData nullAllowed check data size +glBufferSubData check data size +glTexParameter check params 1 +glQueryMatrixxOES check mantissa 16 check exponent 16 return -1 +glDrawTexfvOES check coords 5 +glDrawTexivOES check coords 5 +glDrawTexsvOES check coords 5 +glDrawTexxvOES check coords 5 +glBindFramebufferOES unsupported +glBindRenderbufferOES unsupported +glBlendEquation unsupported +glBlendEquationSeparate unsupported +glBlendFuncSeparate unsupported +glCheckFramebufferStatusOES unsupported return 0 +glCurrentPaletteMatrixOES unsupported +glDeleteFramebuffersOES unsupported +glDeleteRenderbuffersOES unsupported +glFramebufferRenderbufferOES unsupported +glFramebufferStorageOES unsupported +glFramebufferTexture2DOES unsupported +glGenFramebuffersOES unsupported +glGenRenderbuffersOES unsupported +glGenerateMipmapOES unsupported +glGetBufferParameter unsupported +glGetFramebufferAttachmentParameterivOES unsupported +glGetRenderbufferParameterivOES unsupported +glGetTexGen unsupported +glIsFramebufferOES unsupported return JNI_FALSE +glIsRenderbufferOES unsupported return JNI_FALSE +glLoadPaletteFromModelViewMatrixOES unsupported +glMatrixIndexPointerOES unsupported +glRenderbufferStorageOES unsupported return false +glTexGen unsupported +glTexGenf unsupported +glTexGeni unsupported +glTexGenx unsupported +glWeightPointerOES unsupported diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java index 7340357..2cdb244 100644 --- a/opengl/tools/glgen/src/JniCodeEmitter.java +++ b/opengl/tools/glgen/src/JniCodeEmitter.java @@ -893,7 +893,7 @@ public class JniCodeEmitter { ") getDirectBufferPointer(_env, " + cname + "_buf);"); String iii = " "; - out.println(iii + indent + "if ( ! " + cname + " ) {"); + out.println(iii + indent + "if ( ! " + cname + " ) {"); out.println(iii + iii + indent + "return;"); out.println(iii + indent + "}"); } else { @@ -907,13 +907,13 @@ public class JniCodeEmitter { ");"); } + emitNativeBoundsChecks(cfunc, cname, out, true, + emitExceptionCheck, + offset, remaining, nullAllowed ? " " : " "); + if (nullAllowed) { out.println(indent + "}"); } - - emitNativeBoundsChecks(cfunc, cname, out, true, - emitExceptionCheck, - offset, remaining, " "); } } } |