Home | History | Annotate | Download | only in layers
      1 #define LOG_TAG "PictureLayerContent"
      2 #define LOG_NDEBUG 1
      3 
      4 #include "config.h"
      5 #include "PictureLayerContent.h"
      6 
      7 #include "AndroidLog.h"
      8 #include "InspectorCanvas.h"
      9 #include "SkPicture.h"
     10 
     11 #include <dlfcn.h>
     12 #include "SkDevice.h"
     13 
     14 namespace WebCore {
     15 
     16 PictureLayerContent::PictureLayerContent(SkPicture* picture)
     17     : m_picture(picture)
     18     , m_checkedContent(false)
     19     , m_hasText(true)
     20 {
     21     SkSafeRef(m_picture);
     22 }
     23 
     24 PictureLayerContent::PictureLayerContent(const PictureLayerContent& content)
     25     : m_picture(content.m_picture)
     26     , m_checkedContent(content.m_checkedContent)
     27     , m_hasText(content.m_hasText)
     28 {
     29     SkSafeRef(m_picture);
     30 }
     31 
     32 PictureLayerContent::~PictureLayerContent()
     33 {
     34     SkSafeUnref(m_picture);
     35 }
     36 
     37 int PictureLayerContent::width()
     38 {
     39     if (!m_picture)
     40         return 0;
     41     return m_picture->width();
     42 }
     43 
     44 int PictureLayerContent::height()
     45 {
     46     if (!m_picture)
     47         return 0;
     48     return m_picture->height();
     49 }
     50 
     51 void PictureLayerContent::checkForOptimisations()
     52 {
     53     if (!m_checkedContent)
     54         maxZoomScale(); // for now only check the maximum scale for painting
     55 }
     56 
     57 float PictureLayerContent::maxZoomScale()
     58 {
     59     if (m_checkedContent)
     60         return m_hasText ? 1e6 : 1.0;
     61 
     62     // Let's check if we have text or not. If we don't, we can limit
     63     // ourselves to scale 1!
     64     SkBitmap bitmap;
     65     bitmap.setConfig(SkBitmap::kARGB_8888_Config,
     66                      m_picture->width(),
     67                      m_picture->height());
     68     InspectorBounder inspectorBounder;
     69     InspectorCanvas checker(&inspectorBounder, m_picture, bitmap);
     70     checker.drawPicture(*m_picture);
     71     m_hasText = checker.hasText();
     72     if (!checker.hasContent()) {
     73         // no content to draw, discard picture so UI / tile generation
     74         // doesn't bother with it
     75         SkSafeUnref(m_picture);
     76         m_picture = 0;
     77     }
     78 
     79     m_checkedContent = true;
     80 
     81     return m_hasText ? 1e6 : 1.0;
     82 }
     83 
     84 void PictureLayerContent::draw(SkCanvas* canvas)
     85 {
     86     if (!m_picture)
     87         return;
     88 
     89     TRACE_METHOD();
     90     android::Mutex::Autolock lock(m_drawLock);
     91     SkRect r = SkRect::MakeWH(width(), height());
     92     canvas->clipRect(r);
     93     canvas->drawPicture(*m_picture);
     94 }
     95 
     96 void PictureLayerContent::serialize(SkWStream* stream)
     97 {
     98     if (!m_picture)
     99         return;
    100     m_picture->serialize(stream);
    101 }
    102 
    103 
    104 LegacyPictureLayerContent::LegacyPictureLayerContent(SkMemoryStream* pictureStream) {
    105     m_legacyPicture = NULL;
    106     m_width = 0;
    107     m_height = 0;
    108 
    109     // load legacy skia lib (all functions hidden except ones defined below)
    110     m_legacyLib = dlopen("libskia_legacy.so", RTLD_LAZY);
    111     *reinterpret_cast<void**>(&m_createPictureProc) = dlsym(m_legacyLib, "legacy_skia_create_picture");
    112     *reinterpret_cast<void**>(&m_deletePictureProc) = dlsym(m_legacyLib, "legacy_skia_delete_picture");
    113     *reinterpret_cast<void**>(&m_drawPictureProc) = dlsym(m_legacyLib, "legacy_skia_draw_picture");
    114 
    115     const char* error = dlerror();
    116     if (error) {
    117       SkDebugf("Unable to load legacy lib: %s", error);
    118       sk_throw();
    119     }
    120 
    121     // call into library to create picture and set width and height
    122     const int streamLength = pictureStream->getLength() - pictureStream->peek();
    123     int bytesRead = m_createPictureProc(pictureStream->getAtPos(), streamLength,
    124                                         &m_legacyPicture, &m_width, &m_height);
    125     pictureStream->skip(bytesRead);
    126 }
    127 
    128 LegacyPictureLayerContent::~LegacyPictureLayerContent() {
    129     if (m_legacyLib) {
    130         if (m_legacyPicture) {
    131           m_deletePictureProc(m_legacyPicture);
    132         }
    133         dlclose(m_legacyLib);
    134     }
    135 }
    136 
    137 void LegacyPictureLayerContent::draw(SkCanvas* canvas) {
    138     if (!m_legacyPicture) {
    139       return;
    140     }
    141 
    142     // if this is an InspectorCanvas we need to at least draw something to
    143     // ensure that the canvas is not discarded. (We perform a no-op text
    144     // draw in order to trigger the InspectorCanvas into performing high
    145     // fidelity rendering while zooming.
    146     SkPaint paint;
    147     canvas->drawText(NULL, 0, 0, 0, paint);
    148 
    149     // decompose the canvas into basics
    150     void* matrixStorage = malloc(canvas->getTotalMatrix().writeToMemory(NULL));
    151     void* clipStorage = malloc(canvas->getTotalClip().writeToMemory(NULL));
    152 
    153     canvas->getTotalMatrix().writeToMemory(matrixStorage);
    154     canvas->getTotalClip().writeToMemory(clipStorage);
    155 
    156     const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true);
    157     bitmap.lockPixels();
    158 
    159     // pass picture, matrix, clip, and bitmap
    160     m_drawPictureProc(m_legacyPicture, matrixStorage, clipStorage,
    161                       bitmap.width(), bitmap.height(), bitmap.getConfig(),
    162                       bitmap.rowBytes(), bitmap.getPixels());
    163 
    164 
    165     bitmap.unlockPixels();
    166     free(matrixStorage);
    167     free(clipStorage);
    168 }
    169 
    170 } // namespace WebCore
    171