| /* | 
 |  * Copyright 2012 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "GrSurface.h" | 
 | #include "GrSurfacePriv.h" | 
 |  | 
 | #include "SkBitmap.h" | 
 | #include "SkGr.h" | 
 | #include "SkImageEncoder.h" | 
 | #include <stdio.h> | 
 |  | 
 | bool GrSurface::writePixels(int left, int top, int width, int height, | 
 |                             GrPixelConfig config, const void* buffer, size_t rowBytes, | 
 |                             uint32_t pixelOpsFlags) { | 
 |     // go through context so that all necessary flushing occurs | 
 |     GrContext* context = this->getContext(); | 
 |     if (NULL == context) { | 
 |         return false; | 
 |     } | 
 |     return context->writeSurfacePixels(this, left, top, width, height, config, buffer, rowBytes, | 
 |                                        pixelOpsFlags); | 
 | } | 
 |  | 
 | bool GrSurface::readPixels(int left, int top, int width, int height, | 
 |                            GrPixelConfig config, void* buffer, size_t rowBytes, | 
 |                            uint32_t pixelOpsFlags) { | 
 |     // go through context so that all necessary flushing occurs | 
 |     GrContext* context = this->getContext(); | 
 |     if (NULL == context) { | 
 |         return false; | 
 |     } | 
 |     GrRenderTarget* target = this->asRenderTarget(); | 
 |     if (target) { | 
 |         return context->readRenderTargetPixels(target, left, top, width, height, config, buffer, | 
 |                                                rowBytes, pixelOpsFlags); | 
 |     } | 
 |     return false; | 
 | } | 
 |  | 
 | SkImageInfo GrSurface::info() const { | 
 |     SkColorType colorType; | 
 |     if (!GrPixelConfig2ColorType(this->config(), &colorType)) { | 
 |         sk_throw(); | 
 |     } | 
 |     return SkImageInfo::Make(this->width(), this->height(), colorType, kPremul_SkAlphaType); | 
 | } | 
 |  | 
 | // TODO: This should probably be a non-member helper function. It might only be needed in | 
 | // debug or developer builds. | 
 | bool GrSurface::savePixels(const char* filename) { | 
 |     SkBitmap bm; | 
 |     if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(this->width(), this->height()))) { | 
 |         return false; | 
 |     } | 
 |  | 
 |     bool result = this->readPixels(0, 0, this->width(), this->height(), kSkia8888_GrPixelConfig, | 
 |                                    bm.getPixels()); | 
 |     if (!result) { | 
 |         SkDebugf("------ failed to read pixels for %s\n", filename); | 
 |         return false; | 
 |     } | 
 |  | 
 |     // remove any previous version of this file | 
 |     remove(filename); | 
 |  | 
 |     if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) { | 
 |         SkDebugf("------ failed to encode %s\n", filename); | 
 |         remove(filename);   // remove any partial file | 
 |         return false; | 
 |     } | 
 |  | 
 |     return true; | 
 | } | 
 |  | 
 | void GrSurface::flushWrites() { | 
 |     if (!this->wasDestroyed()) { | 
 |         this->getContext()->flushSurfaceWrites(this); | 
 |     } | 
 | } | 
 |  | 
 | void GrSurface::prepareForExternalRead() { | 
 |     if (!this->wasDestroyed()) { | 
 |         this->getContext()->prepareSurfaceForExternalRead(this); | 
 |     } | 
 | } | 
 |  | 
 | bool GrSurface::hasPendingRead() const { | 
 |     const GrTexture* thisTex = this->asTexture(); | 
 |     if (thisTex && thisTex->internalHasPendingRead()) { | 
 |         return true; | 
 |     } | 
 |     const GrRenderTarget* thisRT = this->asRenderTarget(); | 
 |     if (thisRT && thisRT->internalHasPendingRead()) { | 
 |         return true; | 
 |     } | 
 |     return false; | 
 | } | 
 |  | 
 | bool GrSurface::hasPendingWrite() const { | 
 |     const GrTexture* thisTex = this->asTexture(); | 
 |     if (thisTex && thisTex->internalHasPendingWrite()) { | 
 |         return true; | 
 |     } | 
 |     const GrRenderTarget* thisRT = this->asRenderTarget(); | 
 |     if (thisRT && thisRT->internalHasPendingWrite()) { | 
 |         return true; | 
 |     } | 
 |     return false; | 
 | } | 
 |  | 
 | bool GrSurface::hasPendingIO() const { | 
 |     const GrTexture* thisTex = this->asTexture(); | 
 |     if (thisTex && thisTex->internalHasPendingIO()) { | 
 |         return true; | 
 |     } | 
 |     const GrRenderTarget* thisRT = this->asRenderTarget(); | 
 |     if (thisRT && thisRT->internalHasPendingIO()) { | 
 |         return true; | 
 |     } | 
 |     return false; | 
 | } |