| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2010 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2010 Google Inc. All rights reserved. | 3 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. | 4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 } | 80 } |
| 81 | 81 |
| 82 } // anonymous namespace | 82 } // anonymous namespace |
| 83 | 83 |
| 84 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D> we
bContext, bool preserveDrawingBuffer) | 84 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D> we
bContext, bool preserveDrawingBuffer) |
| 85 : m_impl(webContext.get()) | 85 : m_impl(webContext.get()) |
| 86 , m_ownedWebContext(webContext) | 86 , m_ownedWebContext(webContext) |
| 87 , m_initializedAvailableExtensions(false) | 87 , m_initializedAvailableExtensions(false) |
| 88 , m_layerComposited(false) | 88 , m_layerComposited(false) |
| 89 , m_preserveDrawingBuffer(preserveDrawingBuffer) | 89 , m_preserveDrawingBuffer(preserveDrawingBuffer) |
| 90 , m_packAlignment(4) |
| 90 , m_resourceSafety(ResourceSafetyUnknown) | 91 , m_resourceSafety(ResourceSafetyUnknown) |
| 91 , m_grContext(0) | 92 , m_grContext(0) |
| 92 { | 93 { |
| 93 } | 94 } |
| 94 | 95 |
| 95 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3DProv
ider> provider, bool preserveDrawingBuffer) | 96 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3DProv
ider> provider, bool preserveDrawingBuffer) |
| 96 : m_provider(provider) | 97 : m_provider(provider) |
| 97 , m_impl(m_provider->context3d()) | 98 , m_impl(m_provider->context3d()) |
| 98 , m_initializedAvailableExtensions(false) | 99 , m_initializedAvailableExtensions(false) |
| 99 , m_layerComposited(false) | 100 , m_layerComposited(false) |
| 100 , m_preserveDrawingBuffer(preserveDrawingBuffer) | 101 , m_preserveDrawingBuffer(preserveDrawingBuffer) |
| 102 , m_packAlignment(4) |
| 101 , m_resourceSafety(ResourceSafetyUnknown) | 103 , m_resourceSafety(ResourceSafetyUnknown) |
| 102 , m_grContext(m_provider->grContext()) | 104 , m_grContext(m_provider->grContext()) |
| 103 { | 105 { |
| 104 } | 106 } |
| 105 | 107 |
| 106 GraphicsContext3D::~GraphicsContext3D() | 108 GraphicsContext3D::~GraphicsContext3D() |
| 107 { | 109 { |
| 108 setContextLostCallback(nullptr); | 110 setContextLostCallback(nullptr); |
| 109 setErrorMessageCallback(nullptr); | 111 setErrorMessageCallback(nullptr); |
| 110 | 112 |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 DELEGATE_TO_WEBCONTEXT_2(hint, GC3Denum, GC3Denum) | 495 DELEGATE_TO_WEBCONTEXT_2(hint, GC3Denum, GC3Denum) |
| 494 DELEGATE_TO_WEBCONTEXT_1R(isBuffer, Platform3DObject, GC3Dboolean) | 496 DELEGATE_TO_WEBCONTEXT_1R(isBuffer, Platform3DObject, GC3Dboolean) |
| 495 DELEGATE_TO_WEBCONTEXT_1R(isEnabled, GC3Denum, GC3Dboolean) | 497 DELEGATE_TO_WEBCONTEXT_1R(isEnabled, GC3Denum, GC3Dboolean) |
| 496 DELEGATE_TO_WEBCONTEXT_1R(isFramebuffer, Platform3DObject, GC3Dboolean) | 498 DELEGATE_TO_WEBCONTEXT_1R(isFramebuffer, Platform3DObject, GC3Dboolean) |
| 497 DELEGATE_TO_WEBCONTEXT_1R(isProgram, Platform3DObject, GC3Dboolean) | 499 DELEGATE_TO_WEBCONTEXT_1R(isProgram, Platform3DObject, GC3Dboolean) |
| 498 DELEGATE_TO_WEBCONTEXT_1R(isRenderbuffer, Platform3DObject, GC3Dboolean) | 500 DELEGATE_TO_WEBCONTEXT_1R(isRenderbuffer, Platform3DObject, GC3Dboolean) |
| 499 DELEGATE_TO_WEBCONTEXT_1R(isShader, Platform3DObject, GC3Dboolean) | 501 DELEGATE_TO_WEBCONTEXT_1R(isShader, Platform3DObject, GC3Dboolean) |
| 500 DELEGATE_TO_WEBCONTEXT_1R(isTexture, Platform3DObject, GC3Dboolean) | 502 DELEGATE_TO_WEBCONTEXT_1R(isTexture, Platform3DObject, GC3Dboolean) |
| 501 DELEGATE_TO_WEBCONTEXT_1(lineWidth, GC3Dfloat) | 503 DELEGATE_TO_WEBCONTEXT_1(lineWidth, GC3Dfloat) |
| 502 DELEGATE_TO_WEBCONTEXT_1(linkProgram, Platform3DObject) | 504 DELEGATE_TO_WEBCONTEXT_1(linkProgram, Platform3DObject) |
| 503 DELEGATE_TO_WEBCONTEXT_2(pixelStorei, GC3Denum, GC3Dint) | 505 |
| 506 void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param) |
| 507 { |
| 508 if (pname == PACK_ALIGNMENT) |
| 509 m_packAlignment = param; |
| 510 m_impl->pixelStorei(pname, param); |
| 511 } |
| 512 |
| 504 DELEGATE_TO_WEBCONTEXT_2(polygonOffset, GC3Dfloat, GC3Dfloat) | 513 DELEGATE_TO_WEBCONTEXT_2(polygonOffset, GC3Dfloat, GC3Dfloat) |
| 505 | 514 |
| 506 DELEGATE_TO_WEBCONTEXT_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3
Denum, GC3Denum, void*) | 515 DELEGATE_TO_WEBCONTEXT_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3
Denum, GC3Denum, void*) |
| 507 | 516 |
| 508 DELEGATE_TO_WEBCONTEXT(releaseShaderCompiler) | 517 DELEGATE_TO_WEBCONTEXT(releaseShaderCompiler) |
| 509 DELEGATE_TO_WEBCONTEXT_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3
Dsizei) | 518 DELEGATE_TO_WEBCONTEXT_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3
Dsizei) |
| 510 DELEGATE_TO_WEBCONTEXT_2(sampleCoverage, GC3Dclampf, GC3Dboolean) | 519 DELEGATE_TO_WEBCONTEXT_2(sampleCoverage, GC3Dclampf, GC3Dboolean) |
| 511 DELEGATE_TO_WEBCONTEXT_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | 520 DELEGATE_TO_WEBCONTEXT_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) |
| 512 | 521 |
| 513 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& stri
ng) | 522 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& stri
ng) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 { | 606 { |
| 598 if (getContextAttributes().premultipliedAlpha) | 607 if (getContextAttributes().premultipliedAlpha) |
| 599 return 0; | 608 return 0; |
| 600 | 609 |
| 601 Platform3DObject framebufferId; | 610 Platform3DObject framebufferId; |
| 602 int width, height; | 611 int width, height; |
| 603 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; | 612 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; |
| 604 | 613 |
| 605 RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); | 614 RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); |
| 606 unsigned char* pixels = imageData->data()->data(); | 615 unsigned char* pixels = imageData->data()->data(); |
| 607 size_t bufferSize = 4 * width * height; | |
| 608 | 616 |
| 609 m_impl->readBackFramebuffer(pixels, bufferSize, framebufferId, width, height
); | 617 m_impl->bindFramebuffer(FRAMEBUFFER, framebufferId); |
| 610 | 618 readBackFramebuffer(pixels, width, height, ReadbackRGBA, AlphaDoNothing); |
| 611 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 619 flipVertically(pixels, width, height); |
| 612 // If the implementation swapped the red and blue channels, un-swap them. | |
| 613 for (size_t i = 0; i < bufferSize; i += 4) | |
| 614 std::swap(pixels[i], pixels[i + 2]); | |
| 615 #endif | |
| 616 | 620 |
| 617 return imageData.release(); | 621 return imageData.release(); |
| 618 } | 622 } |
| 619 | 623 |
| 624 void GraphicsContext3D::readBackFramebuffer(unsigned char* pixels, int width, in
t height, ReadbackOrder readbackOrder, AlphaOp op) |
| 625 { |
| 626 if (m_packAlignment > 4) |
| 627 m_impl->pixelStorei(PACK_ALIGNMENT, 1); |
| 628 m_impl->readPixels(0, 0, width, height, RGBA, UNSIGNED_BYTE, pixels); |
| 629 if (m_packAlignment > 4) |
| 630 m_impl->pixelStorei(PACK_ALIGNMENT, m_packAlignment); |
| 631 |
| 632 size_t bufferSize = 4 * width * height; |
| 633 |
| 634 if (readbackOrder == ReadbackSkia) { |
| 635 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
| 636 // Swizzle red and blue channels to match SkBitmap's byte ordering. |
| 637 // TODO(kbr): expose GL_BGRA as extension. |
| 638 for (size_t i = 0; i < bufferSize; i += 4) { |
| 639 std::swap(pixels[i], pixels[i + 2]); |
| 640 } |
| 641 #endif |
| 642 } |
| 643 |
| 644 if (op == AlphaDoPremultiply) { |
| 645 for (size_t i = 0; i < bufferSize; i += 4) { |
| 646 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); |
| 647 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); |
| 648 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); |
| 649 } |
| 650 } else if (op != AlphaDoNothing) { |
| 651 ASSERT_NOT_REACHED(); |
| 652 } |
| 653 } |
| 654 |
| 620 DELEGATE_TO_WEBCONTEXT_R(createBuffer, Platform3DObject) | 655 DELEGATE_TO_WEBCONTEXT_R(createBuffer, Platform3DObject) |
| 621 DELEGATE_TO_WEBCONTEXT_R(createFramebuffer, Platform3DObject) | 656 DELEGATE_TO_WEBCONTEXT_R(createFramebuffer, Platform3DObject) |
| 622 DELEGATE_TO_WEBCONTEXT_R(createProgram, Platform3DObject) | 657 DELEGATE_TO_WEBCONTEXT_R(createProgram, Platform3DObject) |
| 623 DELEGATE_TO_WEBCONTEXT_R(createRenderbuffer, Platform3DObject) | 658 DELEGATE_TO_WEBCONTEXT_R(createRenderbuffer, Platform3DObject) |
| 624 DELEGATE_TO_WEBCONTEXT_1R(createShader, GC3Denum, Platform3DObject) | 659 DELEGATE_TO_WEBCONTEXT_1R(createShader, GC3Denum, Platform3DObject) |
| 625 DELEGATE_TO_WEBCONTEXT_R(createTexture, Platform3DObject) | 660 DELEGATE_TO_WEBCONTEXT_R(createTexture, Platform3DObject) |
| 626 | 661 |
| 627 DELEGATE_TO_WEBCONTEXT_1(deleteBuffer, Platform3DObject) | 662 DELEGATE_TO_WEBCONTEXT_1(deleteBuffer, Platform3DObject) |
| 628 DELEGATE_TO_WEBCONTEXT_1(deleteFramebuffer, Platform3DObject) | 663 DELEGATE_TO_WEBCONTEXT_1(deleteFramebuffer, Platform3DObject) |
| 629 DELEGATE_TO_WEBCONTEXT_1(deleteProgram, Platform3DObject) | 664 DELEGATE_TO_WEBCONTEXT_1(deleteProgram, Platform3DObject) |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 case GraphicsContext3D::DEPTH_STENCIL: | 918 case GraphicsContext3D::DEPTH_STENCIL: |
| 884 return ChannelDepth | ChannelStencil; | 919 return ChannelDepth | ChannelStencil; |
| 885 default: | 920 default: |
| 886 return 0; | 921 return 0; |
| 887 } | 922 } |
| 888 } | 923 } |
| 889 | 924 |
| 890 void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int
height, bool premultiplyAlpha, ImageBuffer* imageBuffer) | 925 void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int
height, bool premultiplyAlpha, ImageBuffer* imageBuffer) |
| 891 { | 926 { |
| 892 unsigned char* pixels = 0; | 927 unsigned char* pixels = 0; |
| 893 size_t bufferSize = 4 * width * height; | |
| 894 | 928 |
| 895 const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap(); | 929 const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap(); |
| 896 const SkBitmap* readbackBitmap = 0; | 930 const SkBitmap* readbackBitmap = 0; |
| 897 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); | 931 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); |
| 898 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { | 932 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { |
| 899 // This is the fastest and most common case. We read back | 933 // This is the fastest and most common case. We read back |
| 900 // directly into the canvas's backing store. | 934 // directly into the canvas's backing store. |
| 901 readbackBitmap = canvasBitmap; | 935 readbackBitmap = canvasBitmap; |
| 902 m_resizingBitmap.reset(); | 936 m_resizingBitmap.reset(); |
| 903 } else { | 937 } else { |
| 904 // We need to allocate a temporary bitmap for reading back the | 938 // We need to allocate a temporary bitmap for reading back the |
| 905 // pixel data. We will then use Skia to rescale this bitmap to | 939 // pixel data. We will then use Skia to rescale this bitmap to |
| 906 // the size of the canvas's backing store. | 940 // the size of the canvas's backing store. |
| 907 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { | 941 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { |
| 908 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, heigh
t); | 942 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, heigh
t); |
| 909 if (!m_resizingBitmap.allocPixels()) | 943 if (!m_resizingBitmap.allocPixels()) |
| 910 return; | 944 return; |
| 911 } | 945 } |
| 912 readbackBitmap = &m_resizingBitmap; | 946 readbackBitmap = &m_resizingBitmap; |
| 913 } | 947 } |
| 914 | 948 |
| 915 // Read back the frame buffer. | 949 // Read back the frame buffer. |
| 916 SkAutoLockPixels bitmapLock(*readbackBitmap); | 950 SkAutoLockPixels bitmapLock(*readbackBitmap); |
| 917 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); | 951 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); |
| 918 | 952 |
| 919 m_impl->readBackFramebuffer(pixels, 4 * width * height, framebuffer, width,
height); | 953 m_impl->bindFramebuffer(FRAMEBUFFER, framebuffer); |
| 920 | 954 readBackFramebuffer(pixels, width, height, ReadbackSkia, premultiplyAlpha ?
AlphaDoPremultiply : AlphaDoNothing); |
| 921 if (premultiplyAlpha) { | 955 flipVertically(pixels, width, height); |
| 922 for (size_t i = 0; i < bufferSize; i += 4) { | |
| 923 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); | |
| 924 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); | |
| 925 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); | |
| 926 } | |
| 927 } | |
| 928 | 956 |
| 929 readbackBitmap->notifyPixelsChanged(); | 957 readbackBitmap->notifyPixelsChanged(); |
| 930 if (m_resizingBitmap.readyToDraw()) { | 958 if (m_resizingBitmap.readyToDraw()) { |
| 931 // We need to draw the resizing bitmap into the canvas's backing store. | 959 // We need to draw the resizing bitmap into the canvas's backing store. |
| 932 SkCanvas canvas(*canvasBitmap); | 960 SkCanvas canvas(*canvasBitmap); |
| 933 SkRect dst; | 961 SkRect dst; |
| 934 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); | 962 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); |
| 935 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); | 963 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); |
| 936 } | 964 } |
| 937 } | 965 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 return m_enabledExtensions.contains(mappedName); | 1030 return m_enabledExtensions.contains(mappedName); |
| 1003 } | 1031 } |
| 1004 | 1032 |
| 1005 bool GraphicsContext3D::isExtensionEnabled(const String& name) | 1033 bool GraphicsContext3D::isExtensionEnabled(const String& name) |
| 1006 { | 1034 { |
| 1007 initializeExtensions(); | 1035 initializeExtensions(); |
| 1008 String mappedName = mapExtensionName(name); | 1036 String mappedName = mapExtensionName(name); |
| 1009 return m_enabledExtensions.contains(mappedName); | 1037 return m_enabledExtensions.contains(mappedName); |
| 1010 } | 1038 } |
| 1011 | 1039 |
| 1040 void GraphicsContext3D::flipVertically(uint8_t* framebuffer, int width, int heig
ht) |
| 1041 { |
| 1042 m_scanline.resize(width * 4); |
| 1043 uint8* scanline = &m_scanline[0]; |
| 1044 unsigned rowBytes = width * 4; |
| 1045 unsigned count = height / 2; |
| 1046 for (unsigned i = 0; i < count; i++) { |
| 1047 uint8* rowA = framebuffer + i * rowBytes; |
| 1048 uint8* rowB = framebuffer + (height - i - 1) * rowBytes; |
| 1049 memcpy(scanline, rowB, rowBytes); |
| 1050 memcpy(rowB, rowA, rowBytes); |
| 1051 memcpy(rowA, scanline, rowBytes); |
| 1052 } |
| 1053 } |
| 1054 |
| 1012 } // namespace WebCore | 1055 } // namespace WebCore |
| OLD | NEW |