http://blog.csdn.net/eastmoon502136/article/details/7696928
搞定了android4.0.3的觸摸屏的適配后(其實只要驅動沒有什么問題,加個配置文件就很容易搞定了),新的任務就下來了,就是要尋找 android4.0.3中的鼠標是如何繪畫的,哪里createSurface,哪里分配空間的。因為如果是軟鼠標的話,在播放視頻或者玩大型游戲的時 候是很卡的,而走overlay,硬鼠標的話,就顯得很靈敏了。艱巨的任務啊,看了我好久還是沒有找到鼠標是在哪里繪制的。因為android2.3是在 WindowManagerService里面new了一個surface,接着畫了幾條線而得到的,而android4.0.3中,找了n久還是沒有發 現,可惡的android4.0.3,網上資料也沒有介紹。
期間也添加了android中的power、volumeup、volumedown三個按鍵,雖然基本功能實現了,但是還是沒有搞明白那個長按電源鍵 出來關機和重啟等選項是怎么實現的。無聊之余,把KEY的DOWN和UP順序對調了下,居然有點效果,在此非常疑惑。就是我本來實現的時候,input子 系統上報是
期間也添加了android中的power、volumeup、volumedown三個按鍵,雖然基本功能實現了,但是還是沒有搞明白那個長按電源鍵 出來關機和重啟等選項是怎么實現的。無聊之余,把KEY的DOWN和UP順序對調了下,居然有點效果,在此非常疑惑。就是我本來實現的時候,input子 系統上報是
[html]
view plain
copy
- input_report_key(&button_dev, KEY_POWER, 1);
[html]
view plain
copy
- input_report_key(&button_dev, KEY_POWER, 0);
這樣可以實現電源鍵的鎖屏功能。但當我交換了上報的順尋后也就是
[html]
view plain
copy
[html]
view plain
copy
- input_report_key(&button_dev, KEY_POWER, 0);
- <pre class="html" name="code">input_report_key(&button_dev, KEY_POWER, 1);</pre><br>
- <pre></pre>
- <p>居 然是那個長按鍵的功能,不知道哪位高手可以指導一下,這個還是得等找到了鼠標繪制的地方后再深入下去吧。 一直以為surface的創建是 在WindowManagerService中實現的,沒想到,這個android4.0.3居然把surface創建,鼠標繪制放在了input下了, 這個可惡的SpriteController.cpp,目錄/frameworks/base/services/input /SpriteController.cpp。找得心灰意冷啊。居然中文解釋說是精靈,怪不得這么難找呢。網上找了下,說java中好像是有一個 Sprite的東東,說是什么繪圖時候用的,這不正好是鼠標嗎,小小的精靈,難怪鼠標也是天藍色透明的了,看來寫這個代碼的高手還真的別有一番寓意啊,在 此膜拜下。
- 由於本人還是菜鳥,學電子的孩子,C++和Java接觸好少,看不大懂,只能簡單的了解下。先看看Sprite類的定義。注釋的已經很清楚了,六級都沒過的我也能看懂,相信難不倒你了。</p>
- <pre class="html" name="code">class Sprite : public RefBase {
- protected:
- Sprite() { }
- virtual ~Sprite() { }
- public:
- enum {
- // The base layer for pointer sprites.
- BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
- // The base layer for spot sprites.
- BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
- };
- /* Sets the bitmap that is drawn by the sprite.
- * The sprite retains a copy of the bitmap for subsequent rendering. */
- virtual void setIcon(const SpriteIcon& icon) = 0;
- inline void clearIcon() {
- setIcon(SpriteIcon());
- }
- /* Sets whether the sprite is visible. */
- virtual void setVisible(bool visible) = 0;
- /* Sets the sprite position on screen, relative to the sprite's hot spot. */
- virtual void setPosition(float x, float y) = 0;
- /* Sets the layer of the sprite, relative to the system sprite overlay layer.
- * Layer 0 is the overlay layer, > 0 appear above this layer. */
- virtual void setLayer(int32_t layer) = 0;
- /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
- virtual void setAlpha(float alpha) = 0;
- /* Sets the sprite transformation matrix. */
- virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
- };
- </pre>
- <p><br>
- 一開始的搜尋路線是找到鼠標那個png圖片是哪里調用的,鼠標早就不叫mouse了,cursor或者pointer早就替換了mouse了。鼠標的圖標是在EventHub發現了鼠標這個驅動</p>
- <p>(android4.0.3 中應該是cursor這個驅動)后再由frameworks/base/core/java/android/view /PointerIcon.java中的getSystemIcon()導入,然后再由 SpriteController::SpriteImpl::setIcon()(c++的類的繼承,虛函數,各種糾結,只能稍微理解)設置為 Sprite這個精靈的資源。每次鼠標移動后,InputReader線程總會獲取這個坐標值,然后InputDispatch會分發給 WindowManagerService,而ViewRootImpl會讀取等等,這個網上講得已經很詳細了。<br>
- 對於鼠標,應該也是pointer,input目錄下面還有一個PointerController,看着這個名字,就知道了,這個肯定是控制鼠標啊, 觸摸屏啊什么的。具體看注釋吧,寫得夠直</p>
- <p>白的。</p>
- <pre class="html" name="code">/**
- * Interface for tracking a mouse / touch pad pointer and touch pad spots.
- *
- * The spots are sprites on screen that visually represent the positions of
- * fingers
- *
- * The pointer controller is responsible for providing synchronization and for tracking
- * display orientation changes if needed.
- */
- class PointerControllerInterface : public virtual RefBase {
- protected:
- PointerControllerInterface() { }
- virtual ~PointerControllerInterface() { }
- public:
- /* Gets the bounds of the region that the pointer can traverse.
- * Returns true if the bounds are available. */
- virtual bool getBounds(float* outMinX, float* outMinY,
- float* outMaxX, float* outMaxY) const = 0;
- /* Move the pointer. */
- virtual void move(float deltaX, float deltaY) = 0;
- /* Sets a mask that indicates which buttons are pressed. */
- virtual void setButtonState(int32_t buttonState) = 0;
- /* Gets a mask that indicates which buttons are pressed. */
- virtual int32_t getButtonState() const = 0;
- /* Sets the absolute location of the pointer. */
- virtual void setPosition(float x, float y) = 0;
- /* Gets the absolute location of the pointer. */
- virtual void getPosition(float* outX, float* outY) const = 0;
- enum Transition {
- // Fade/unfade immediately.
- TRANSITION_IMMEDIATE,
- // Fade/unfade gradually.
- TRANSITION_GRADUAL,
- };
- /* Fades the pointer out now. */
- virtual void fade(Transition transition) = 0;
- /* Makes the pointer visible if it has faded out.
- * The pointer never unfades itself automatically. This method must be called
- * by the client whenever the pointer is moved or a button is pressed and it
- * wants to ensure that the pointer becomes visible again. */
- virtual void unfade(Transition transition) = 0;
- enum Presentation {
- // Show the mouse pointer.
- PRESENTATION_POINTER,
- // Show spots and a spot anchor in place of the mouse pointer.
- PRESENTATION_SPOT,
- };
- /* Sets the mode of the pointer controller. */
- virtual void setPresentation(Presentation presentation) = 0;
- /* Sets the spots for the current gesture.
- * The spots are not subject to the inactivity timeout like the pointer
- * itself it since they are expected to remain visible for so long as
- * the fingers are on the touch pad.
- *
- * The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant.
- * For spotCoords, pressure != 0 indicates that the spot's location is being
- * pressed (not hovering).
- */
- virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
- BitSet32 spotIdBits) = 0;
- /* Removes all spots. */
- virtual void clearSpots() = 0;
- };
- /*
- * Pointer resources.
- */
- struct PointerResources {
- SpriteIcon spotHover;
- SpriteIcon spotTouch;
- SpriteIcon spotAnchor;
- };
- </pre>
- <p><br>
- 而 PointerController是繼承PointerControllerInterface的。突然看到這下面那兩行英文,這么熟悉,這么刺眼,頓 時覺得,晴空霹靂啊,明明寫得這么清楚了,畫pointer精靈到surface,這,,讓我情何以堪,找了這么久,蒼天呢,都怪C++不夠好有木有,英 語不夠牛有不有。其實android中很多函數的功能都在他的類的定義中有說明的,何不仔細研究.h呢?而把大把大把的時間浪費在.cpp中了,經驗啊, 經驗不足啊。</p>
- <pre class="html" name="code">/*
- * Tracks pointer movements and draws the pointer sprite to a surface.
- *
- * Handles pointer acceleration and animation.
- */
- class PointerController : public PointerControllerInterface, public MessageHandler
- 好了,發泄好了,而在Sprite中,最重要的就是SpriteController::doUpdateSprites()這個函數了,這里就是鼠標繪制和移動后更新的全過程了。
- void SpriteController::doUpdateSprites() {
- // Collect information about sprite updates.
- // Each sprite update record includes a reference to its associated sprite so we can
- // be certain the sprites will not be deleted while this function runs. Sprites
- // may invalidate themselves again during this time but we will handle those changes
- // in the next iteration.
- Vector<SpriteUpdate> updates;
- size_t numSprites;
- { // acquire lock
- AutoMutex _l(mLock);
- numSprites = mLocked.invalidatedSprites.size();
- for (size_t i = 0; i < numSprites; i++) {
- const sp<SpriteImpl>& sprite = mLocked.invalidatedSprites.itemAt(i);
- updates.push(SpriteUpdate(sprite, sprite->getStateLocked()));
- sprite->resetDirtyLocked();
- }
- mLocked.invalidatedSprites.clear();
- } // release lock
- // Create missing surfaces.
- bool surfaceChanged = false;
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
- if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) {
- update.state.surfaceWidth = update.state.icon.bitmap.width();
- update.state.surfaceHeight = update.state.icon.bitmap.height();
- update.state.surfaceDrawn = false;
- update.state.surfaceVisible = false;
- update.state.surfaceControl = obtainSurface(
- update.state.surfaceWidth, update.state.surfaceHeight);
- if (update.state.surfaceControl != NULL) {
- update.surfaceChanged = surfaceChanged = true;
- }
- }
- }
- // Resize sprites if needed, inside a global transaction.
- bool haveGlobalTransaction = false;
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
- if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) {
- int32_t desiredWidth = update.state.icon.bitmap.width();
- int32_t desiredHeight = update.state.icon.bitmap.height();
- if (update.state.surfaceWidth < desiredWidth
- || update.state.surfaceHeight < desiredHeight) {
- if (!haveGlobalTransaction) {
- SurfaceComposerClient::openGlobalTransaction();
- haveGlobalTransaction = true;
- }
- status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight);
- if (status) {
- LOGE("Error %d resizing sprite surface from %dx%d to %dx%d",
- status, update.state.surfaceWidth, update.state.surfaceHeight,
- desiredWidth, desiredHeight);
- } else {
- update.state.surfaceWidth = desiredWidth;
- update.state.surfaceHeight = desiredHeight;
- update.state.surfaceDrawn = false;
- update.surfaceChanged = surfaceChanged = true;
- if (update.state.surfaceVisible) {
- status = update.state.surfaceControl->hide();
- if (status) {
- LOGE("Error %d hiding sprite surface after resize.", status);
- } else {
- update.state.surfaceVisible = false;
- }
- }
- }
- }
- }
- }
- if (haveGlobalTransaction) {
- SurfaceComposerClient::closeGlobalTransaction();
- }
- // Redraw sprites if needed.
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
- if ((update.state.dirty & DIRTY_BITMAP) && update.state.surfaceDrawn) {
- update.state.surfaceDrawn = false;
- update.surfaceChanged = surfaceChanged = true;
- }
- if (update.state.surfaceControl != NULL && !update.state.surfaceDrawn
- && update.state.wantSurfaceVisible()) {
- sp<Surface> surface = update.state.surfaceControl->getSurface();
- Surface::SurfaceInfo surfaceInfo;
- status_t status = surface->lock(&surfaceInfo);
- if (status) {
- LOGE("Error %d locking sprite surface before drawing.", status);
- } else {
- SkBitmap surfaceBitmap;
- ssize_t bpr = surfaceInfo.s * bytesPerPixel(surfaceInfo.format);
- surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config,
- surfaceInfo.w, surfaceInfo.h, bpr);
- surfaceBitmap.setPixels(surfaceInfo.bits);
- SkCanvas surfaceCanvas;
- surfaceCanvas.setBitmapDevice(surfaceBitmap);
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
- if (surfaceInfo.w > uint32_t(update.state.icon.bitmap.width())) {
- paint.setColor(0); // transparent fill color
- surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
- surfaceInfo.w, update.state.icon.bitmap.height(), paint);
- }
- if (surfaceInfo.h > uint32_t(update.state.icon.bitmap.height())) {
- paint.setColor(0); // transparent fill color
- surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
- surfaceInfo.w, surfaceInfo.h, paint);
- }
- status = surface->unlockAndPost();
- if (status) {
- LOGE("Error %d unlocking and posting sprite surface after drawing.", status);
- } else {
- update.state.surfaceDrawn = true;
- update.surfaceChanged = surfaceChanged = true;
- }
- }
- }
- }
- // Set sprite surface properties and make them visible.
- bool haveTransaction = false;
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
- bool wantSurfaceVisibleAndDrawn = update.state.wantSurfaceVisible()
- && update.state.surfaceDrawn;
- bool becomingVisible = wantSurfaceVisibleAndDrawn && !update.state.surfaceVisible;
- bool becomingHidden = !wantSurfaceVisibleAndDrawn && update.state.surfaceVisible;
- if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden
- || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
- | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
- | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
- status_t status;
- if (!haveTransaction) {
- SurfaceComposerClient::openGlobalTransaction();
- haveTransaction = true;
- }
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) {
- status = update.state.surfaceControl->setAlpha(update.state.alpha);
- if (status) {
- LOGE("Error %d setting sprite surface alpha.", status);
- }
- }
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible || (update.state.dirty & (DIRTY_POSITION
- | DIRTY_HOTSPOT)))) {
- status = update.state.surfaceControl->setPosition(
- update.state.positionX - update.state.icon.hotSpotX,
- update.state.positionY - update.state.icon.hotSpotY);
- if (status) {
- LOGE("Error %d setting sprite surface position.", status);
- }
- }
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible
- || (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) {
- status = update.state.surfaceControl->setMatrix(
- update.state.transformationMatrix.dsdx,
- update.state.transformationMatrix.dtdx,
- update.state.transformationMatrix.dsdy,
- update.state.transformationMatrix.dtdy);
- if (status) {
- LOGE("Error %d setting sprite surface transformation matrix.", status);
- }
- }
- int32_t surfaceLayer = mOverlayLayer + update.state.layer;
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible || (update.state.dirty & DIRTY_LAYER))) {
- status = update.state.surfaceControl->setLayer(surfaceLayer);
- if (status) {
- LOGE("Error %d setting sprite surface layer.", status);
- }
- }
- if (becomingVisible) {
- status = update.state.surfaceControl->show(surfaceLayer);
- if (status) {
- LOGE("Error %d showing sprite surface.", status);
- } else {
- update.state.surfaceVisible = true;
- update.surfaceChanged = surfaceChanged = true;
- }
- } else if (becomingHidden) {
- status = update.state.surfaceControl->hide();
- if (status) {
- LOGE("Error %d hiding sprite surface.", status);
- } else {
- update.state.surfaceVisible = false;
- update.surfaceChanged = surfaceChanged = true;
- }
- }
- }
- }
- if (haveTransaction) {
- SurfaceComposerClient::closeGlobalTransaction();
- }
- // If any surfaces were changed, write back the new surface properties to the sprites.
- if (surfaceChanged) { // acquire lock
- AutoMutex _l(mLock);
- for (size_t i = 0; i < numSprites; i++) {
- const SpriteUpdate& update = updates.itemAt(i);
- if (update.surfaceChanged) {
- update.sprite->setSurfaceLocked(update.state.surfaceControl,
- update.state.surfaceWidth, update.state.surfaceHeight,
- update.state.surfaceDrawn, update.state.surfaceVisible);
- }
- }
- } // release lock
- // Clear the sprite update vector outside the lock. It is very important that
- // we do not clear sprite references inside the lock since we could be releasing
- // the last remaining reference to the sprite here which would result in the
- // sprite being deleted and the lock being reacquired by the sprite destructor
- // while already held.
- updates.clear();
- }
- </pre>
- <p><br>
- 看到 update.state.surfaceControl = obtainSurface(update.state.surfaceWidth, update.state.surfaceHeight); 其實就是創建了一個surface,在一開始進入的主界面</p>
- <p>的時候,鼠標是沒有的,當移動了下鼠標或者點擊了下鼠標后就執行這個創建了這個surface,有logcat后的信息為證(只可惜公司nta內的東西拿不出來)。</p>
- <pre class="html" name="code">sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height) {
- ensureSurfaceComposerClient();
- sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface(
- String8("Sprite"), 0, width, height, PIXEL_FORMAT_RGBA_8888);
- if (surfaceControl == NULL || !surfaceControl->isValid()
- || !surfaceControl->getSurface()->isValid()) {
- LOGE("Error creating sprite surface.");
- return NULL;
- }
- return surfaceControl;
- }
- </pre>
- <p><br>
- 而創建完后,必須得分配空間啊,surface的信息也得錄入啊。具體就在下面了</p>
- <p> </p>
- <pre class="html" name="code">sp<Surface> surface = update.state.surfaceControl->getSurface();
- Surface::SurfaceInfo surfaceInfo;
- status_t status = surface->lock(&surfaceInfo);
- </pre>
- <p><br>
- 看到lock()了嗎?就是這,繼續跟進代碼<br>
- </p>
- <pre class="html" name="code">status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) {
- ANativeWindow_Buffer outBuffer;
- ARect temp;
- ARect* inOutDirtyBounds = NULL;
- if (inOutDirtyRegion) {
- temp = inOutDirtyRegion->getBounds();
- inOutDirtyBounds = &temp;
- }
- status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);
- if (err == NO_ERROR) {
- other->w = uint32_t(outBuffer.width);
- other->h = uint32_t(outBuffer.height);
- other->s = uint32_t(outBuffer.stride);
- other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
- other->format = uint32_t(outBuffer.format);
- other->bits = outBuffer.bits;
- }
- if (inOutDirtyRegion) {
- inOutDirtyRegion->set( static_cast<Rect const&>(temp) );
- }
- return err;
- }
- </pre>
- <p><br>
- 也 行你會說,怎么這個lock有兩個參數的,明顯不對嗎,好吧,看來我的C++還是有點基礎的,后悔以前搞ACM的時候只是一個main函數到底,沒有好好 用C++來實現,要不然現在也肯定是個大牛了。看看這個 status_t lock(SurfaceInfo* info, Region* dirty = NULL);明白了吧?使用了默認的參數,剛開始還以為這個lock是假的。哈哈接着,看到了SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);了吧,好明顯的說,接着看看這個函數到底干了什么了</p>
- <pre class="html" name="code">status_t SurfaceTextureClient::lock(
- ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
- {
- if (mLockedBuffer != 0) {
- LOGE("Surface::lock failed, already locked");
- return INVALID_OPERATION;
- }
- if (!mConnectedToCpu) {
- int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);
- if (err) {
- return err;
- }
- // we're intending to do software rendering from this point
- setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
- }
- ANativeWindowBuffer* out;
- status_t err = dequeueBuffer(&out);
- LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
- if (err == NO_ERROR) {
- sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
- err = lockBuffer(backBuffer.get());
- LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
- backBuffer->handle, strerror(-err));
- if (err == NO_ERROR) {
- const Rect bounds(backBuffer->width, backBuffer->height);
- Region newDirtyRegion;
- if (inOutDirtyBounds) {
- newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
- newDirtyRegion.andSelf(bounds);
- } else {
- newDirtyRegion.set(bounds);
- }
- // figure out if we can copy the frontbuffer back
- const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
- const bool canCopyBack = (frontBuffer != 0 &&
- backBuffer->width == frontBuffer->width &&
- backBuffer->height == frontBuffer->height &&
- backBuffer->format == frontBuffer->format);
- if (canCopyBack) {
- // copy the area that is invalid and not repainted this round
- const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
- if (!copyback.isEmpty())
- copyBlt(backBuffer, frontBuffer, copyback);
- } else {
- // if we can't copy-back anything, modify the user's dirty
- // region to make sure they redraw the whole buffer
- newDirtyRegion.set(bounds);
- }
- // keep track of the are of the buffer that is "clean"
- // (ie: that will be redrawn)
- mOldDirtyRegion = newDirtyRegion;
- if (inOutDirtyBounds) {
- *inOutDirtyBounds = newDirtyRegion.getBounds();
- }
- void* vaddr;
- status_t res = backBuffer->lock(
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- newDirtyRegion.bounds(), &vaddr);
- LOGW_IF(res, "failed locking buffer (handle = %p)",
- backBuffer->handle);
- mLockedBuffer = backBuffer;
- outBuffer->width = backBuffer->width;
- outBuffer->height = backBuffer->height;
- outBuffer->stride = backBuffer->stride;
- outBuffer->format = backBuffer->format;
- outBuffer->bits = vaddr;
- }
- }
- return err;
- }
- </pre>
- <p><br>
- 好了,找到了 ANativeWindowBuffer* out; status_t err = dequeueBuffer(&out);差不多告一段落了,代碼看着頭暈,還是分析不大來額。菜鳥有待提高,打好基礎,慢慢</p>
- <p>地分析。</p>
- <pre class="html" name="code">int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
- LOGV("SurfaceTextureClient::dequeueBuffer");
- Mutex::Autolock lock(mMutex);
- int buf = -1;
- status_t result = mSurfaceTexture->dequeueBuffer(&buf, mReqWidth, mReqHeight,
- mReqFormat, mReqUsage);
- if (result < 0) {
- LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
- "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
- result);
- return result;
- }
- sp<GraphicBuffer>& gbuf(mSlots[buf]);
- if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {
- freeAllBuffers();
- }
- if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
- result = mSurfaceTexture->requestBuffer(buf, &gbuf);
- if (result != NO_ERROR) {
- LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",
- result);
- return result;
- }
- }
- *buffer = gbuf.get();
- return OK;
- }
- </pre>
- <p><br>
- 由於對surface很多的概念還不是很清楚,分析代碼也有點難度。只能拿出來,慢慢啃了。快要下班了,就這么着吧。android的圖形顯示系統好復雜好復雜啊,看得我頭都大</p>
- <p>了。不過結合板子和代碼慢慢調試倒是可以理解得很好。不錯。還有就是代碼中的英文得好好啃,看來單詞還得好好記啊。<br>
- </p>
- <pre></pre>
- <pre></pre>