Bug 1890689 accumulate input in LargerReceiverBlockSizeThanDesiredBuffering GTest...
[gecko.git] / gfx / 2d / SourceSurfaceCairo.cpp
blob3bf380c35faf5a0d18bc01ef0a07350faef6af42
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "SourceSurfaceCairo.h"
8 #include "DrawTargetCairo.h"
9 #include "HelpersCairo.h"
10 #include "DataSourceSurfaceWrapper.h"
12 #include "cairo.h"
14 namespace mozilla {
15 namespace gfx {
17 static SurfaceFormat CairoFormatToSurfaceFormat(cairo_format_t format) {
18 switch (format) {
19 case CAIRO_FORMAT_ARGB32:
20 return SurfaceFormat::B8G8R8A8;
21 case CAIRO_FORMAT_RGB24:
22 return SurfaceFormat::B8G8R8X8;
23 case CAIRO_FORMAT_RGB16_565:
24 return SurfaceFormat::R5G6B5_UINT16;
25 case CAIRO_FORMAT_A8:
26 return SurfaceFormat::A8;
27 default:
28 return SurfaceFormat::B8G8R8A8;
32 SourceSurfaceCairo::SourceSurfaceCairo(
33 cairo_surface_t* aSurface, const IntSize& aSize,
34 const SurfaceFormat& aFormat, DrawTargetCairo* aDrawTarget /* = nullptr */)
35 : mSize(aSize),
36 mFormat(aFormat),
37 mSurface(aSurface),
38 mDrawTarget(aDrawTarget) {
39 cairo_surface_reference(mSurface);
42 SourceSurfaceCairo::~SourceSurfaceCairo() { cairo_surface_destroy(mSurface); }
44 IntSize SourceSurfaceCairo::GetSize() const { return mSize; }
46 SurfaceFormat SourceSurfaceCairo::GetFormat() const { return mFormat; }
48 already_AddRefed<DataSourceSurface> SourceSurfaceCairo::GetDataSurface() {
49 RefPtr<DataSourceSurface> dataSurf;
51 if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
52 dataSurf = new DataSourceSurfaceCairo(mSurface);
53 } else {
54 cairo_surface_t* imageSurf = cairo_image_surface_create(
55 GfxFormatToCairoFormat(mFormat), mSize.width, mSize.height);
57 // Fill the new image surface with the contents of our surface.
58 cairo_t* ctx = cairo_create(imageSurf);
59 cairo_set_source_surface(ctx, mSurface, 0, 0);
60 cairo_paint(ctx);
61 cairo_destroy(ctx);
63 dataSurf = new DataSourceSurfaceCairo(imageSurf);
64 cairo_surface_destroy(imageSurf);
67 // We also need to make sure that the returned surface has
68 // surface->GetType() == SurfaceType::DATA.
69 return MakeAndAddRef<DataSourceSurfaceWrapper>(dataSurf);
72 cairo_surface_t* SourceSurfaceCairo::GetSurface() const { return mSurface; }
74 void SourceSurfaceCairo::DrawTargetWillChange() {
75 if (mDrawTarget) {
76 mDrawTarget = nullptr;
78 // We're about to lose our version of the surface, so make a copy of it.
79 cairo_surface_t* surface = cairo_surface_create_similar(
80 mSurface, GfxFormatToCairoContent(mFormat), mSize.width, mSize.height);
81 cairo_t* ctx = cairo_create(surface);
82 cairo_pattern_t* pat = cairo_pattern_create_for_surface(mSurface);
83 cairo_set_source(ctx, pat);
84 cairo_paint(ctx);
85 cairo_destroy(ctx);
86 cairo_pattern_destroy(pat);
88 // Swap in this new surface.
89 cairo_surface_destroy(mSurface);
90 mSurface = surface;
94 DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t* imageSurf)
95 : mImageSurface(imageSurf) {
96 cairo_surface_reference(mImageSurface);
99 DataSourceSurfaceCairo::~DataSourceSurfaceCairo() {
100 cairo_surface_destroy(mImageSurface);
103 unsigned char* DataSourceSurfaceCairo::GetData() {
104 return cairo_image_surface_get_data(mImageSurface);
107 int32_t DataSourceSurfaceCairo::Stride() {
108 return cairo_image_surface_get_stride(mImageSurface);
111 IntSize DataSourceSurfaceCairo::GetSize() const {
112 IntSize size;
113 size.width = cairo_image_surface_get_width(mImageSurface);
114 size.height = cairo_image_surface_get_height(mImageSurface);
116 return size;
119 SurfaceFormat DataSourceSurfaceCairo::GetFormat() const {
120 return CairoFormatToSurfaceFormat(
121 cairo_image_surface_get_format(mImageSurface));
124 cairo_surface_t* DataSourceSurfaceCairo::GetSurface() const {
125 return mImageSurface;
128 } // namespace gfx
129 } // namespace mozilla