SkSurface_Gpu.cpp revision fbfcd5602128ec010c82cb733c9cdc0a3254f9f3
15d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com/*
25d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com * Copyright 2012 Google Inc.
35d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com *
45d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com * Use of this source code is governed by a BSD-style license that can be
55d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com * found in the LICENSE file.
65d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com */
75d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
85d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkSurface_Base.h"
95d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkImagePriv.h"
105d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkCanvas.h"
115d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com#include "SkMallocPixelRef.h"
125d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
135d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comstatic const size_t kIgnoreRowBytesValue = (size_t)~0;
145d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
155d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comclass SkSurface_Gpu : public SkSurface_Base {
165d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.compublic:
175d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    static bool Valid(const SkImage::Info&, SkColorSpace*, size_t rb = kIgnoreRowBytesValue);
185d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
195d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    SkSurface_Gpu(const SkImage::Info&, SkColorSpace*, void*, size_t rb);
205d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    SkSurface_Gpu(const SkImage::Info&, SkColorSpace*, SkPixelRef*, size_t rb);
215d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
225d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
235d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    virtual SkSurface* onNewSurface(const SkImage::Info&, SkColorSpace*) SK_OVERRIDE;
245d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    virtual SkImage* onNewImageShapshot() SK_OVERRIDE;
255d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
265d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                        const SkPaint*) SK_OVERRIDE;
275d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
285d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comprivate:
295d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    SkBitmap    fBitmap;
305d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    bool        fWeOwnThePixels;
315d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
325d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    typedef SkSurface_Base INHERITED;
335d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com};
345d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
355d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com///////////////////////////////////////////////////////////////////////////////
365d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
375d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.combool SkSurface_Gpu::Valid(const SkImage::Info& info, SkColorSpace* cs,
385d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                             size_t rowBytes) {
395d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    static const size_t kMaxTotalSize = SK_MaxS32;
405d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
415d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    bool isOpaque;
425d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
435d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
445d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    int shift = 0;
455d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    switch (config) {
465d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        case SkBitmap::kA8_Config:
475d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com            shift = 0;
485d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com            break;
495d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        case SkBitmap::kRGB_565_Config:
505d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com            shift = 1;
515d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com            break;
525d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        case SkBitmap::kARGB_8888_Config:
535d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com            shift = 2;
545d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com            break;
555d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        default:
565d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com            return false;
575d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
585d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
595d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    // TODO: examine colorspace
605d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
615d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (kIgnoreRowBytesValue == rowBytes) {
625d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        return true;
635d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
645d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
655d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    uint64_t minRB = (uint64_t)info.fWidth << shift;
665d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (minRB > rowBytes) {
675d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        return false;
685d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
695d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
705d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    size_t alignedRowBytes = rowBytes >> shift << shift;
715d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (alignedRowBytes != rowBytes) {
725d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        return false;
735d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
745d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
755d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    uint64_t size = (uint64_t)info.fHeight * rowBytes;
765d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (size > kMaxTotalSize) {
775d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        return false;
785d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
805d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    return true;
815d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
825d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
835d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface_Gpu::SkSurface_Gpu(const SkImage::Info& info, SkColorSpace* cs,
845d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                                   void* pixels, size_t rb)
855d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        : INHERITED(info.fWidth, info.fHeight) {
865d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    bool isOpaque;
875d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
88fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
895d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fBitmap.setConfig(config, info.fWidth, info.fHeight, rb);
905d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fBitmap.setPixels(pixels);
915d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fBitmap.setIsOpaque(isOpaque);
925d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fWeOwnThePixels = false;
935d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
945d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
955d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface_Gpu::SkSurface_Gpu(const SkImage::Info& info, SkColorSpace* cs,
965d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                                   SkPixelRef* pr, size_t rb)
975d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        : INHERITED(info.fWidth, info.fHeight) {
985d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    bool isOpaque;
995d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
1005d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1015d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fBitmap.setConfig(config, info.fWidth, info.fHeight, rb);
1025d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fBitmap.setPixelRef(pr);
1035d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fBitmap.setIsOpaque(isOpaque);
1045d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    fWeOwnThePixels = true;
1055d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1065d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (!isOpaque) {
1075d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        fBitmap.eraseColor(0);
1085d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
1095d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
1105d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1115d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkCanvas* SkSurface_Gpu::onNewCanvas() {
1125d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    return SkNEW_ARGS(SkCanvas, (fBitmap));
1135d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
1145d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1155d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface* SkSurface_Gpu::onNewSurface(const SkImage::Info& info,
1165d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                                          SkColorSpace* cs) {
1175d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    return SkSurface::NewRaster(info, cs);
1185d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
1195d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1205d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkImage* SkSurface_Gpu::onNewImageShapshot() {
1215d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    // if we don't own the pixels, we need to make a deep-copy
1225d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    // if we do, we need to perform a copy-on-write the next time
1235d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    // we draw to this bitmap from our canvas...
1245d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    return SkNewImageFromBitmap(fBitmap);
1255d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
1265d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1275d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comvoid SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
1285d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                              const SkPaint* paint) {
1295d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    canvas->drawBitmap(fBitmap, x, y, paint);
1305d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
1315d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1325d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com///////////////////////////////////////////////////////////////////////////////
1335d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1345d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface* SkSurface::NewRenderTargetDirect(GrContext* ctx,
1355d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                                            GrRenderTarget* target) {
1365d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (NULL == ctx || NULL == target) {
1375d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        return NULL;
1385d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
139fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1405d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    return SkNEW_ARGS(SkSurface_Gpu, (ctx, target));
1415d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
1425d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
1435d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comSkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImage::Info& info,
1445d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com                                      SkColorSpace*, int sampleCount) {
1455d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (NULL == ctx) {
1465d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        return NULL;
1475d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
1485d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    if (!SkSurface_Gpu::Valid(info, cs, sampleCount)) {
1495d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com        return NULL;
1505d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    }
151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1525d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com//    return SkNEW_ARGS(SkSurface_Gpu, (info, cs, pr, rowBytes));
1535d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com}
1545d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
155