Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright 2011, The Android Open Source Project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *  * Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  *  * Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef TransferQueue_h
     27 #define TransferQueue_h
     28 
     29 #if USE(ACCELERATED_COMPOSITING)
     30 
     31 #include "GLUtils.h"
     32 #include "ShaderProgram.h"
     33 #include "SkBitmap.h"
     34 #include <utils/StrongPointer.h>
     35 #include <utils/threads.h>
     36 
     37 namespace WebCore {
     38 
     39 class Tile;
     40 class TilePainter;
     41 class TileTexture;
     42 
     43 struct GLState {
     44     GLint bufferId[1];
     45     GLint viewport[4];
     46     GLboolean scissor[1];
     47     GLboolean depth[1];
     48     GLfloat clearColor[4];
     49 };
     50 
     51 
     52 // While in the queue, the Tile can be re-used, the updated bitmap
     53 // can be discarded. In order to track this obsolete base tiles, we save
     54 // the Tile's Info to make the comparison.
     55 // At the time of base tile's dtor or webview destroy, we want to discard
     56 // all the data in the queue. However, we have to do the Surface Texture
     57 // update in the same GL context as the UI thread. So we mark the status
     58 // as pendingDiscard, and delay the Surface Texture operation to the next
     59 // draw call.
     60 
     61 enum TransferItemStatus {
     62     emptyItem = 0, // S.T. buffer ready for new content
     63     pendingBlit = 1, // Ready for bliting into tile's GL Tex.
     64     pendingDiscard = 2 // Waiting for the next draw call to discard
     65 };
     66 
     67 enum TextureUploadType {
     68     CpuUpload = 0,
     69     GpuUpload = 1
     70 };
     71 
     72 #define DEFAULT_UPLOAD_TYPE GpuUpload
     73 
     74 class TileTransferData {
     75 public:
     76     TileTransferData()
     77     : status(emptyItem)
     78     , savedTilePtr(0)
     79     , savedTilePainter(0)
     80     , savedTileTexturePtr(0)
     81     , uploadType(DEFAULT_UPLOAD_TYPE)
     82     , bitmap(0)
     83     {
     84     }
     85 
     86     ~TileTransferData()
     87     {
     88         // Bitmap will be created lazily, need to delete them at dtor.
     89         delete bitmap;
     90     }
     91 
     92     TransferItemStatus status;
     93     Tile* savedTilePtr;
     94     TilePainter* savedTilePainter; // Ref count the tilePainter to keep the tile alive.
     95     TileTexture* savedTileTexturePtr;
     96     TextureUploadType uploadType;
     97     // This is only useful in Cpu upload code path, so it will be dynamically
     98     // lazily allocated.
     99     SkBitmap* bitmap;
    100 
    101     // Specific data to the pure color tiles' queue.
    102     Color pureColor;
    103 };
    104 
    105 class TransferQueue {
    106 public:
    107     TransferQueue(bool useMinimalMem);
    108     ~TransferQueue();
    109 
    110     // This will be called by the browser through nativeSetProperty
    111     void setTextureUploadType(TextureUploadType type);
    112     void updateDirtyTiles();
    113 
    114     void initGLResources(int width, int height);
    115 
    116     // insert the bitmap into the queue, mark the tile dirty if failing
    117     void updateQueueWithBitmap(const TileRenderInfo* renderInfo,
    118                                const SkBitmap& bitmap);
    119 
    120     void addItemInTransferQueue(const TileRenderInfo* info,
    121                                 TextureUploadType type,
    122                                 const SkBitmap* bitmap);
    123     // Check if the item @ index is ready for update.
    124     // The lock will be done when returning true.
    125     bool readyForUpdate();
    126 
    127     void lockQueue() { m_transferQueueItemLocks.lock(); }
    128     void unlockQueue() { m_transferQueueItemLocks.unlock(); }
    129 
    130     void addItemInPureColorQueue(const TileRenderInfo* renderInfo);
    131 
    132     void cleanupGLResourcesAndQueue();
    133 
    134     bool needsInit() { return !m_sharedSurfaceTextureId; }
    135     void resetQueue();
    136     // This queue can be accessed from UI and TexGen thread, therefore, we need
    137     // a lock to protect its access
    138     TileTransferData* m_transferQueue;
    139 
    140     android::sp<ANativeWindow> m_ANW;
    141 
    142     // EGL wrapper around m_ANW for use by the GaneshRenderer
    143     EGLSurface m_eglSurface;
    144 
    145 private:
    146     // return true if successfully inserted into queue
    147     bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
    148                                   const SkBitmap& bitmap);
    149     bool getHasGLContext();
    150     void setHasGLContext(bool hasContext);
    151     void emptyAndAbandonQueue();
    152 
    153     int getNextTransferQueueIndex();
    154 
    155     // Save and restore the GL State while switching from/to FBO.
    156     void saveGLState();
    157     void setGLStateForCopy(int width, int height);
    158     void restoreGLState();
    159 
    160     // Check the current transfer queue item is obsolete or not.
    161     bool checkObsolete(const TileTransferData* data);
    162 
    163     void setPendingDiscard();
    164     // Before each draw call and the blit operation, clean up all the
    165     // pendingDiscard items.
    166     void cleanupPendingDiscard();
    167     void cleanupGLResources();
    168 
    169     void blitTileFromQueue(GLuint fboID, TileTexture* destTex,
    170                            GLuint srcTexId, GLenum srcTexTarget,
    171                            int index);
    172 
    173     void clearItemInTranferQueue(int index);
    174     void addItemCommon(const TileRenderInfo* renderInfo,
    175                        TextureUploadType type, TileTransferData* data);
    176 
    177     void updatePureColorTiles();
    178     void clearPureColorQueue();
    179     // Note that the m_transferQueueIndex only changed in the TexGen thread
    180     // where we are going to move on to update the next item in the queue.
    181     int m_transferQueueIndex;
    182 
    183     GLuint m_fboID; // The FBO used for copy the SurfTex to each tile
    184 
    185     GLuint m_sharedSurfaceTextureId;
    186 
    187     // GLContext can be lost when WebView destroyed.
    188     bool m_hasGLContext;
    189 
    190     GLState m_GLStateBeforeBlit;
    191     android::sp<android::SurfaceTexture> m_sharedSurfaceTexture;
    192 
    193     int m_emptyItemCount;
    194 
    195     // We are using wait/signal to handle our own queue sync.
    196     // First of all, if we don't have our own lock, then while WebView is
    197     // destroyed, the UI thread will wait for the Tex Gen to get out from
    198     // dequeue operation, which will not succeed. B/c at this moment, we
    199     // already lost the GL Context.
    200     // Now we maintain a counter, which is m_emptyItemCount. When this reach
    201     // 0, then we need the Tex Gen thread to wait. UI thread can signal this
    202     // wait after calling updateTexImage at the draw call , or after WebView
    203     // is destroyed.
    204     android::Mutex m_transferQueueItemLocks;
    205     android::Condition m_transferQueueItemCond;
    206 
    207     EGLDisplay m_currentDisplay;
    208 
    209     // This should be GpuUpload for production, but for debug purpose or working
    210     // around driver/HW issue, we can set it to CpuUpload.
    211     TextureUploadType m_currentUploadType;
    212 
    213     // The non-pure-color tile are 1 to 1 mapping with Surface Texture which is
    214     // resource limited. To get better performance, it is better to separate
    215     // the pure color tile into another queue.
    216     WTF::Vector<TileTransferData> m_pureColorTileQueue;
    217 
    218     // The number of items transfer queue can buffer up.
    219     int m_transferQueueSize;
    220 };
    221 
    222 } // namespace WebCore
    223 
    224 #endif // USE(ACCELERATED_COMPOSITING)
    225 #endif // TransferQueue_h
    226