aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2017-04-28 11:33:28 +0200
committerPierre Ossman <ossman@cendio.se>2017-04-28 12:58:57 +0200
commitee234fe36a4d8be3baea010b22fe3019518625ce (patch)
treeb019eb0fa1d56b161e4ab4a2906feebbca525e7f
parent819f297de50d6d713d5b1a5f1031b97f09a4f7a1 (diff)
downloadtigervnc-ee234fe36a4d8be3baea010b22fe3019518625ce.tar.gz
tigervnc-ee234fe36a4d8be3baea010b22fe3019518625ce.zip
Create new CGImage for each draw
The system expects these to be immutable, so changing the data after creation only works in some special cases. We need to recreate the CGImage object each time we've changed something. (cherry picked from commit 3b347313f1880c0744fd7aa29f45ea010dcfcf42)
-rw-r--r--vncviewer/Surface.h1
-rw-r--r--vncviewer/Surface_OSX.cxx81
2 files changed, 46 insertions, 36 deletions
diff --git a/vncviewer/Surface.h b/vncviewer/Surface.h
index 032889b4..1cb87f50 100644
--- a/vncviewer/Surface.h
+++ b/vncviewer/Surface.h
@@ -60,7 +60,6 @@ protected:
HBITMAP bitmap;
#elif defined(__APPLE__)
unsigned char* data;
- CGImageRef image;
#else
Pixmap pixmap;
Picture picture;
diff --git a/vncviewer/Surface_OSX.cxx b/vncviewer/Surface_OSX.cxx
index 668187bc..10d1e3e2 100644
--- a/vncviewer/Surface_OSX.cxx
+++ b/vncviewer/Surface_OSX.cxx
@@ -28,13 +28,47 @@
#include "Surface.h"
-static void render(CGContextRef gc, CGImageRef image,
+static CGImageRef create_image(const unsigned char* data,
+ int w, int h)
+{
+ CGColorSpaceRef lut;
+ CGDataProviderRef provider;
+
+ CGImageRef image;
+
+ lut = CGDisplayCopyColorSpace(kCGDirectMainDisplay);
+ if (!lut) {
+ lut = CGColorSpaceCreateDeviceRGB();
+ if (!lut)
+ throw rdr::Exception("CGColorSpaceCreateDeviceRGB");
+ }
+
+ provider = CGDataProviderCreateWithData(NULL, data,
+ w * h * 4, NULL);
+ if (!provider)
+ throw rdr::Exception("CGDataProviderCreateWithData");
+
+ image = CGImageCreate(w, h, 8, 32, w * 4, lut,
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little,
+ provider, NULL, false, kCGRenderingIntentDefault);
+ CGColorSpaceRelease(lut);
+ CGDataProviderRelease(provider);
+ if (!image)
+ throw rdr::Exception("CGImageCreate");
+
+ return image;
+}
+
+static void render(CGContextRef gc,
+ const unsigned char* data,
CGBlendMode mode, CGFloat alpha,
- int src_x, int src_y,
+ int src_x, int src_y, int src_w, int src_h,
int x, int y, int w, int h)
{
CGRect rect;
- CGImageRef subimage;
+ CGImageRef image, subimage;
+
+ image = create_image(data, src_w, src_h);
rect.origin.x = src_x;
rect.origin.y = src_y;
@@ -60,6 +94,7 @@ static void render(CGContextRef gc, CGImageRef image,
CGContextRestoreGState(gc);
CGImageRelease(subimage);
+ CGImageRelease(image);
}
static CGContextRef make_bitmap(int width, int height, unsigned char* data)
@@ -114,8 +149,8 @@ void Surface::draw(int src_x, int src_y, int x, int y, int w, int h)
// macOS Coordinates are from bottom left, not top left
y = Fl_Window::current()->h() - (y + h);
- render(fl_gc, image, kCGBlendModeCopy, 1.0,
- src_x, src_y, x, y, w, h);
+ render(fl_gc, data, kCGBlendModeCopy, 1.0,
+ src_x, src_y, width(), height(), x, y, w, h);
CGContextRestoreGState(fl_gc);
}
@@ -129,8 +164,8 @@ void Surface::draw(Surface* dst, int src_x, int src_y, int x, int y, int w, int
// macOS Coordinates are from bottom left, not top left
y = dst->height() - (y + h);
- render(bitmap, image, kCGBlendModeCopy, 1.0,
- src_x, src_y, x, y, w, h);
+ render(bitmap, data, kCGBlendModeCopy, 1.0,
+ src_x, src_y, width(), height(), x, y, w, h);
CGContextRelease(bitmap);
}
@@ -146,8 +181,8 @@ void Surface::blend(int src_x, int src_y, int x, int y, int w, int h, int a)
// macOS Coordinates are from bottom left, not top left
y = Fl_Window::current()->h() - (y + h);
- render(fl_gc, image, kCGBlendModeNormal, (CGFloat)a/255.0,
- src_x, src_y, x, y, w, h);
+ render(fl_gc, data, kCGBlendModeNormal, (CGFloat)a/255.0,
+ src_x, src_y, width(), height(), x, y, w, h);
CGContextRestoreGState(fl_gc);
}
@@ -161,43 +196,19 @@ void Surface::blend(Surface* dst, int src_x, int src_y, int x, int y, int w, int
// macOS Coordinates are from bottom left, not top left
y = dst->height() - (y + h);
- render(bitmap, image, kCGBlendModeNormal, (CGFloat)a/255.0,
- src_x, src_y, x, y, w, h);
+ render(bitmap, data, kCGBlendModeNormal, (CGFloat)a/255.0,
+ src_x, src_y, width(), height(), x, y, w, h);
CGContextRelease(bitmap);
}
void Surface::alloc()
{
- CGColorSpaceRef lut;
- CGDataProviderRef provider;
-
data = new unsigned char[width() * height() * 4];
-
- lut = CGDisplayCopyColorSpace(kCGDirectMainDisplay);
- if (!lut) {
- lut = CGColorSpaceCreateDeviceRGB();
- if (!lut)
- throw rdr::Exception("CGColorSpaceCreateDeviceRGB");
- }
-
- provider = CGDataProviderCreateWithData(NULL, data,
- width() * height() * 4, NULL);
- if (!provider)
- throw rdr::Exception("CGDataProviderCreateWithData");
-
- image = CGImageCreate(width(), height(), 8, 32, width() * 4, lut,
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little,
- provider, NULL, false, kCGRenderingIntentDefault);
- CGColorSpaceRelease(lut);
- CGDataProviderRelease(provider);
- if (!image)
- throw rdr::Exception("CGImageCreate");
}
void Surface::dealloc()
{
- CGImageRelease(image);
delete [] data;
}