gfx/skia/trunk/src/image/SkSurface_Raster.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/image/SkSurface_Raster.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,161 @@
     1.4 +/*
     1.5 + * Copyright 2012 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "SkSurface_Base.h"
    1.12 +#include "SkImagePriv.h"
    1.13 +#include "SkCanvas.h"
    1.14 +#include "SkDevice.h"
    1.15 +#include "SkMallocPixelRef.h"
    1.16 +
    1.17 +static const size_t kIgnoreRowBytesValue = (size_t)~0;
    1.18 +
    1.19 +class SkSurface_Raster : public SkSurface_Base {
    1.20 +public:
    1.21 +    static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue);
    1.22 +
    1.23 +    SkSurface_Raster(const SkImageInfo&, void*, size_t rb);
    1.24 +    SkSurface_Raster(SkPixelRef*);
    1.25 +
    1.26 +    virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
    1.27 +    virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
    1.28 +    virtual SkImage* onNewImageSnapshot() SK_OVERRIDE;
    1.29 +    virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
    1.30 +                        const SkPaint*) SK_OVERRIDE;
    1.31 +    virtual void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE;
    1.32 +
    1.33 +private:
    1.34 +    SkBitmap    fBitmap;
    1.35 +    bool        fWeOwnThePixels;
    1.36 +
    1.37 +    typedef SkSurface_Base INHERITED;
    1.38 +};
    1.39 +
    1.40 +///////////////////////////////////////////////////////////////////////////////
    1.41 +
    1.42 +bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) {
    1.43 +    static const size_t kMaxTotalSize = SK_MaxS32;
    1.44 +
    1.45 +    int shift = 0;
    1.46 +    switch (info.fColorType) {
    1.47 +        case kAlpha_8_SkColorType:
    1.48 +            shift = 0;
    1.49 +            break;
    1.50 +        case kRGB_565_SkColorType:
    1.51 +            shift = 1;
    1.52 +            break;
    1.53 +        case kPMColor_SkColorType:
    1.54 +            shift = 2;
    1.55 +            break;
    1.56 +        default:
    1.57 +            return false;
    1.58 +    }
    1.59 +
    1.60 +    if (kIgnoreRowBytesValue == rowBytes) {
    1.61 +        return true;
    1.62 +    }
    1.63 +
    1.64 +    uint64_t minRB = (uint64_t)info.fWidth << shift;
    1.65 +    if (minRB > rowBytes) {
    1.66 +        return false;
    1.67 +    }
    1.68 +
    1.69 +    size_t alignedRowBytes = rowBytes >> shift << shift;
    1.70 +    if (alignedRowBytes != rowBytes) {
    1.71 +        return false;
    1.72 +    }
    1.73 +
    1.74 +    uint64_t size = sk_64_mul(info.fHeight, rowBytes);
    1.75 +    if (size > kMaxTotalSize) {
    1.76 +        return false;
    1.77 +    }
    1.78 +
    1.79 +    return true;
    1.80 +}
    1.81 +
    1.82 +SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb)
    1.83 +    : INHERITED(info)
    1.84 +{
    1.85 +    fBitmap.setConfig(info, rb);
    1.86 +    fBitmap.setPixels(pixels);
    1.87 +    fWeOwnThePixels = false;    // We are "Direct"
    1.88 +}
    1.89 +
    1.90 +SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr)
    1.91 +    : INHERITED(pr->info().fWidth, pr->info().fHeight)
    1.92 +{
    1.93 +    const SkImageInfo& info = pr->info();
    1.94 +
    1.95 +    fBitmap.setConfig(info, info.minRowBytes());
    1.96 +    fBitmap.setPixelRef(pr);
    1.97 +    fWeOwnThePixels = true;
    1.98 +
    1.99 +    if (!info.isOpaque()) {
   1.100 +        fBitmap.eraseColor(SK_ColorTRANSPARENT);
   1.101 +    }
   1.102 +}
   1.103 +
   1.104 +SkCanvas* SkSurface_Raster::onNewCanvas() {
   1.105 +    return SkNEW_ARGS(SkCanvas, (fBitmap));
   1.106 +}
   1.107 +
   1.108 +SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) {
   1.109 +    return SkSurface::NewRaster(info);
   1.110 +}
   1.111 +
   1.112 +void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
   1.113 +                              const SkPaint* paint) {
   1.114 +    canvas->drawBitmap(fBitmap, x, y, paint);
   1.115 +}
   1.116 +
   1.117 +SkImage* SkSurface_Raster::onNewImageSnapshot() {
   1.118 +    return SkNewImageFromBitmap(fBitmap, fWeOwnThePixels);
   1.119 +}
   1.120 +
   1.121 +void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
   1.122 +    // are we sharing pixelrefs with the image?
   1.123 +    SkASSERT(NULL != this->getCachedImage());
   1.124 +    if (SkBitmapImageGetPixelRef(this->getCachedImage()) == fBitmap.pixelRef()) {
   1.125 +        SkASSERT(fWeOwnThePixels);
   1.126 +        if (kDiscard_ContentChangeMode == mode) {
   1.127 +            fBitmap.setPixelRef(NULL);
   1.128 +            fBitmap.allocPixels();
   1.129 +        } else {
   1.130 +            SkBitmap prev(fBitmap);
   1.131 +            prev.deepCopyTo(&fBitmap);
   1.132 +        }
   1.133 +        // Now fBitmap is a deep copy of itself (and therefore different from
   1.134 +        // what is being used by the image. Next we update the canvas to use
   1.135 +        // this as its backend, so we can't modify the image's pixels anymore.
   1.136 +        SkASSERT(NULL != this->getCachedCanvas());
   1.137 +        this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap);
   1.138 +    }
   1.139 +}
   1.140 +
   1.141 +///////////////////////////////////////////////////////////////////////////////
   1.142 +
   1.143 +SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
   1.144 +    if (!SkSurface_Raster::Valid(info, rowBytes)) {
   1.145 +        return NULL;
   1.146 +    }
   1.147 +    if (NULL == pixels) {
   1.148 +        return NULL;
   1.149 +    }
   1.150 +
   1.151 +    return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rowBytes));
   1.152 +}
   1.153 +
   1.154 +SkSurface* SkSurface::NewRaster(const SkImageInfo& info) {
   1.155 +    if (!SkSurface_Raster::Valid(info)) {
   1.156 +        return NULL;
   1.157 +    }
   1.158 +
   1.159 +    SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL));
   1.160 +    if (NULL == pr.get()) {
   1.161 +        return NULL;
   1.162 +    }
   1.163 +    return SkNEW_ARGS(SkSurface_Raster, (pr));
   1.164 +}

mercurial