merge with changes for GPU backend



git-svn-id: http://skia.googlecode.com/svn/trunk@637 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp
index 5c96e21..2169bc0 100644
--- a/src/utils/mac/SkCreateCGImageRef.cpp
+++ b/src/utils/mac/SkCreateCGImageRef.cpp
@@ -26,22 +26,19 @@
             *bitsPerComponent = 8;
 #if defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 0, 8, 16) \
  || defined(SK_CPU_BENDIAN) && HAS_ARGB_SHIFTS(0, 24, 16, 8)
-            *info = kCGBitmapByteOrder32Big |
-                    kCGImageAlphaPremultipliedLast;
+            *info = kCGBitmapByteOrder32Big;
 #elif defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0) \
    || defined(SK_CPU_BENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0)
             // Matches the CGBitmapInfo that Apple recommends for best
             // performance, used by google chrome.
-            *info = kCGBitmapByteOrder32Host |
-                    kCGImageAlphaPremultipliedFirst;
+            *info = kCGBitmapByteOrder32Little;
 #else
 // ...add more formats as required...
 #warning Cannot convert SkBitmap to CGImageRef with these shiftmasks. \
             This will probably not work.
             // Legacy behavior. Perhaps turn this into an error at some
             // point.
-            *info = kCGBitmapByteOrder32Big |
-                    kCGImageAlphaPremultipliedLast;
+            *info = kCGBitmapByteOrder32Big;
 #endif
             break;
 #if 0
@@ -59,6 +56,10 @@
             return NULL;
     }
 
+    if (!bm.isOpaque()) {
+        *info |= kCGImageAlphaPremultipliedLast;
+    }
+
     SkBitmap* copy;
     if (upscaleTo32) {
         copy = new SkBitmap;
@@ -93,7 +94,7 @@
     CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s,
 															 SkBitmap_ReleaseInfo);
 
-    CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
     CGImageRef ref = CGImageCreate(w, h, bitsPerComponent,
                                    bitmap->bytesPerPixel() * 8,
                                    bitmap->rowBytes(), space, info, dataRef,
@@ -103,4 +104,23 @@
     return ref;
 }
 
+void SkCGDrawBitmap(CGContextRef cg, const SkBitmap& bm, float x, float y) {
+    CGImageRef img = SkCreateCGImageRef(bm);
+
+    if (img) {
+        CGRect r = CGRectMake(0, 0, bm.width(), bm.height());
+        
+        CGContextSaveGState(cg);
+        CGContextTranslateCTM(cg, x, r.size.height + y);
+        CGContextScaleCTM(cg, 1, -1);
+        
+        CGContextDrawImage(cg, r, img);
+        
+        CGContextRestoreGState(cg);
+        
+        CGImageRelease(img);
+    }
+}
+
+
 
diff --git a/src/utils/mac/SkOSWindow_Mac.cpp b/src/utils/mac/SkOSWindow_Mac.cpp
index eb07e2a..6828a95 100644
--- a/src/utils/mac/SkOSWindow_Mac.cpp
+++ b/src/utils/mac/SkOSWindow_Mac.cpp
@@ -2,6 +2,8 @@
 
 #if defined(SK_BUILD_FOR_MAC) && !defined(SK_USE_WXWIDGETS)
 
+#include <AGL/agl.h>
+
 #include <Carbon/Carbon.h>
 #include "SkCGUtils.h"
 
@@ -82,7 +84,7 @@
     pos->offset = 0;
 }
 
-SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd)
+SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd), fAGLCtx(NULL)
 {
 	OSStatus    result;
     WindowRef   wr = (WindowRef)hWnd;
@@ -450,5 +452,79 @@
 	}
 }
 
+AGLContext create_gl(WindowRef wref, bool offscreen)
+{
+    GLint major, minor;
+    AGLContext ctx;
+    
+    aglGetVersion(&major, &minor);
+    SkDebugf("---- agl version %d %d\n", major, minor);
+    
+    const GLint pixelAttrs[] = {
+        AGL_RGBA,
+        AGL_STENCIL_SIZE, 8,
+        AGL_SAMPLE_BUFFERS_ARB, 1,
+		AGL_MULTISAMPLE,
+		AGL_SAMPLES_ARB, 2,        
+		(offscreen ? AGL_OFFSCREEN : AGL_ACCELERATED),
+        (offscreen ? AGL_NONE : AGL_DOUBLEBUFFER),
+        AGL_NONE
+    };
+    AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, pixelAttrs);
+    //AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
+    SkDebugf("----- agl format %p\n", format);
+    ctx = aglCreateContext(format, NULL);
+    SkDebugf("----- agl context %p\n", ctx);
+    aglDestroyPixelFormat(format);
+
+    static const GLint interval = 1;
+    aglSetInteger(ctx, AGL_SWAP_INTERVAL, &interval);
+    aglSetCurrentContext(ctx);
+    return ctx;
+}
+
+bool SkOSWindow::attachGL(const SkBitmap* offscreen)
+{
+    if (NULL == fAGLCtx) {
+        fAGLCtx = create_gl((WindowRef)fHWND, NULL != offscreen);
+        if (NULL == fAGLCtx) {
+            return false;
+        }
+    }
+
+    GLboolean success = true;
+
+    if (offscreen) {
+        success = aglSetOffScreen((AGLContext)fAGLCtx,
+                                    offscreen->width(),
+                                    offscreen->height(),
+                                    offscreen->rowBytes(),
+                                    offscreen->getPixels());
+    } else {
+        success = aglSetWindowRef((AGLContext)fAGLCtx, (WindowRef)fHWND);
+    }
+
+    GLenum err = aglGetError();
+    if (err) {
+        SkDebugf("---- setoffscreen %d %d %s [%d %d]\n", success, err,
+                 aglErrorString(err), offscreen->width(), offscreen->height());
+    }
+    
+    if (success) {
+        glClearColor(0, 0, 0, 0);
+        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    }
+    return success;
+}
+
+void SkOSWindow::detachGL() {
+    aglSetWindowRef((AGLContext)fAGLCtx, NULL);
+}
+
+void SkOSWindow::presentGL() {
+    aglSwapBuffers((AGLContext)fAGLCtx);
+    glFlush();
+}
+
 #endif