1/* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "GrSurface.h" 9#include "GrSurfacePriv.h" 10 11#include "SkBitmap.h" 12#include "SkGr.h" 13#include "SkImageEncoder.h" 14#include <stdio.h> 15 16bool GrSurface::writePixels(int left, int top, int width, int height, 17 GrPixelConfig config, const void* buffer, size_t rowBytes, 18 uint32_t pixelOpsFlags) { 19 // go through context so that all necessary flushing occurs 20 GrContext* context = this->getContext(); 21 if (NULL == context) { 22 return false; 23 } 24 return context->writeSurfacePixels(this, left, top, width, height, config, buffer, rowBytes, 25 pixelOpsFlags); 26} 27 28bool GrSurface::readPixels(int left, int top, int width, int height, 29 GrPixelConfig config, void* buffer, size_t rowBytes, 30 uint32_t pixelOpsFlags) { 31 // go through context so that all necessary flushing occurs 32 GrContext* context = this->getContext(); 33 if (NULL == context) { 34 return false; 35 } 36 GrRenderTarget* target = this->asRenderTarget(); 37 if (target) { 38 return context->readRenderTargetPixels(target, left, top, width, height, config, buffer, 39 rowBytes, pixelOpsFlags); 40 } 41 return false; 42} 43 44SkImageInfo GrSurface::info() const { 45 SkColorType colorType; 46 SkColorProfileType profileType; 47 if (!GrPixelConfig2ColorAndProfileType(this->config(), &colorType, &profileType)) { 48 sk_throw(); 49 } 50 return SkImageInfo::Make(this->width(), this->height(), colorType, kPremul_SkAlphaType, 51 profileType); 52} 53 54// TODO: This should probably be a non-member helper function. It might only be needed in 55// debug or developer builds. 56bool GrSurface::savePixels(const char* filename) { 57 SkBitmap bm; 58 if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(this->width(), this->height()))) { 59 return false; 60 } 61 62 bool result = this->readPixels(0, 0, this->width(), this->height(), kSkia8888_GrPixelConfig, 63 bm.getPixels()); 64 if (!result) { 65 SkDebugf("------ failed to read pixels for %s\n", filename); 66 return false; 67 } 68 69 // remove any previous version of this file 70 remove(filename); 71 72 if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) { 73 SkDebugf("------ failed to encode %s\n", filename); 74 remove(filename); // remove any partial file 75 return false; 76 } 77 78 return true; 79} 80 81void GrSurface::flushWrites() { 82 if (!this->wasDestroyed()) { 83 this->getContext()->flushSurfaceWrites(this); 84 } 85} 86 87void GrSurface::prepareForExternalRead() { 88 if (!this->wasDestroyed()) { 89 this->getContext()->prepareSurfaceForExternalRead(this); 90 } 91} 92 93bool GrSurface::hasPendingRead() const { 94 const GrTexture* thisTex = this->asTexture(); 95 if (thisTex && thisTex->internalHasPendingRead()) { 96 return true; 97 } 98 const GrRenderTarget* thisRT = this->asRenderTarget(); 99 if (thisRT && thisRT->internalHasPendingRead()) { 100 return true; 101 } 102 return false; 103} 104 105bool GrSurface::hasPendingWrite() const { 106 const GrTexture* thisTex = this->asTexture(); 107 if (thisTex && thisTex->internalHasPendingWrite()) { 108 return true; 109 } 110 const GrRenderTarget* thisRT = this->asRenderTarget(); 111 if (thisRT && thisRT->internalHasPendingWrite()) { 112 return true; 113 } 114 return false; 115} 116 117bool GrSurface::hasPendingIO() const { 118 const GrTexture* thisTex = this->asTexture(); 119 if (thisTex && thisTex->internalHasPendingIO()) { 120 return true; 121 } 122 const GrRenderTarget* thisRT = this->asRenderTarget(); 123 if (thisRT && thisRT->internalHasPendingIO()) { 124 return true; 125 } 126 return false; 127} 128