1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_CAIRO_H_ 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_CAIRO_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_device.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _cairo_surface cairo_surface_t; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Image byte ordering on Linux: 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pixels are packed into 32-bit words these days. Even for 24-bit images, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// often 8-bits will be left unused for alignment reasons. Thus, when you see 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ARGB as the byte order you have to wonder if that's in memory order or 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// little-endian order. Here I'll write A.R.G.B to specifiy the memory order. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GdkPixbuf's provide a nice backing store and defaults to R.G.B.A order. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// They'll do the needed byte swapping to match the X server when drawn. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Skia can be controled in skia/include/corecg/SkUserConfig.h (see bits about 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SK_R32_SHIFT). For Linux we define it to be ARGB in registers. For little 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// endian machines that means B.G.R.A in memory. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The image loaders are controlled in 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webkit/port/platform/image-decoders/ImageDecoder.h (see setRGBA). These are 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// also configured for ARGB in registers. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Cairo's only 32-bit mode is ARGB in registers. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// X servers commonly have a 32-bit visual with xRGB in registers (since they 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// typically don't do alpha blending of drawables at the user level. Composite 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extensions aside.) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We don't use GdkPixbuf because its byte order differs from the rest. Most 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// importantly, it differs from Cairo which, being a system library, is 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// something that we can't easily change. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace skia { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the Linux bitmap backing for Skia. We create a Cairo image surface 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to store the backing buffer. This buffer is BGRA in memory (on little-endian 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// machines). 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For now we are also using Cairo to paint to the Drawables so we provide an 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// accessor for getting the surface. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is all quite ok for test_shell. In the future we will want to use 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shared memory between the renderer and the main process at least. In this 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// case we'll probably create the buffer from a precreated region of memory. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a BitmapPlatformDeviceLinux from an already constructed bitmap; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // you should probably be using Create(). This may become private later if 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we ever have to share state between some native drawing UI and Skia, like 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Windows and Mac versions of this class do. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This object takes ownership of @cairo. 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BitmapPlatformDevice(const SkBitmap& other, cairo_t* cairo); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BitmapPlatformDevice(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constructs a device with size |width| * |height| with contents initialized 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to zero. |is_opaque| should be set if the caller knows the bitmap will be 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completely opaque and allows some optimizations. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BitmapPlatformDevice* Create(int width, int height, bool is_opaque); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs the same construction as Create. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Other ports require a separate construction routine because Create does not 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize the bitmap to 0. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BitmapPlatformDevice* CreateAndClear(int width, int height, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This doesn't take ownership of |data|. If |data| is NULL, the contents 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the device are initialized to 0. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BitmapPlatformDevice* Create(int width, int height, bool is_opaque, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t* data); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Overridden from SkBaseDevice: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkClipStack&) OVERRIDE; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overridden from PlatformDevice: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual cairo_t* BeginPlatformPaint() OVERRIDE; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DrawToNativeContext(PlatformSurface surface, int x, int y, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PlatformRect* src_rect) OVERRIDE; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Usage usage) OVERRIDE; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BitmapPlatformDevice* Create(int width, int height, bool is_opaque, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_t* surface); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sets the transform and clip operations. This will not update the Cairo 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // context, but will mark the config as dirty. The next call of LoadConfig 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // will pick up these changes. 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void SetMatrixClip(const SkMatrix& transform, const SkRegion& region); 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Loads the current transform and clip into the context. 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void LoadConfig(); 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Graphics context used to draw into the surface. 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cairo_t* cairo_; 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // True when there is a transform or clip that has not been set to the 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // context. The context is retrieved for every text operation, and the 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // transform and clip do not change as much. We can save time by not loading 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the clip and transform for every one. 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool config_dirty_; 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Translation assigned to the context: we need to keep track of this 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // separately so it can be updated even if the context isn't created yet. 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkMatrix transform_; 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The current clipping 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SkRegion clip_region_; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace skia 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_CAIRO_H_ 133