Back to index

lightning-sunbird  0.9+nobinonly
nsDrawingSurfaceBeOS.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s): Sergei Dolgov
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsDrawingSurfaceBeOS.h"
00039 #include "nsCoord.h"
00040 
00041 NS_IMPL_ISUPPORTS2(nsDrawingSurfaceBeOS, nsIDrawingSurface, nsIDrawingSurfaceBeOS)
00042 
00043 #ifdef CHEAP_PERFORMANCE_MEASUREMENT 
00044 static PRTime mLockTime, mUnlockTime; 
00045 #endif 
00046  
00047 nsDrawingSurfaceBeOS :: nsDrawingSurfaceBeOS()
00048 {
00049   mView = nsnull;
00050   mBitmap = nsnull;
00051   mWidth = 0; 
00052   mHeight = 0; 
00053   mLockFlags = 0;
00054   mLocked = PR_FALSE;
00055 }
00056 
00057 nsDrawingSurfaceBeOS :: ~nsDrawingSurfaceBeOS()
00058 {
00059   if(mBitmap)
00060   {
00061     // Deleting mBitmap will also remove and delete any child views
00062     mBitmap->Unlock();
00063     delete mBitmap;
00064     mView = nsnull;
00065     mBitmap = nsnull;
00066   }
00067 }
00068 
00086 NS_IMETHODIMP nsDrawingSurfaceBeOS :: Lock(PRInt32 aX, PRInt32 aY,
00087                                           PRUint32 aWidth, PRUint32 aHeight,
00088                                           void **aBits, PRInt32 *aStride,
00089                                           PRInt32 *aWidthBytes, PRUint32 aFlags)
00090 {
00091   mLockFlags = aFlags;
00092 
00093   if (mBitmap && !mLocked)
00094   {
00095     if (mView)
00096       mView->Sync();
00097     if (mLockFlags & NS_LOCK_SURFACE_READ_ONLY)
00098       mBitmap->LockBits();
00099     *aStride = mBitmap->BytesPerRow();
00100     *aBits = (uint8 *)mBitmap->Bits() + aX*4 + *aStride * aY;
00101     *aWidthBytes = aWidth*4;
00102     mLocked = PR_TRUE; 
00103   }
00104   else
00105   {
00106     NS_ASSERTION(0, "nested lock attempt");
00107     return NS_ERROR_FAILURE;
00108   }
00109   return NS_OK;
00110 }
00111 
00112 NS_IMETHODIMP nsDrawingSurfaceBeOS :: Unlock(void)
00113 {
00114   if (mBitmap && mLocked)
00115   {
00116     if (mLockFlags & NS_LOCK_SURFACE_READ_ONLY)
00117       mBitmap->UnlockBits();
00118     mLocked = PR_FALSE; 
00119   }
00120   return NS_OK;
00121 }
00122 
00123 
00124 NS_IMETHODIMP nsDrawingSurfaceBeOS :: GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight)
00125 {
00126   *aWidth = mWidth;
00127   *aHeight = mHeight;
00128 
00129   return NS_OK;
00130 }
00131 
00132 NS_IMETHODIMP nsDrawingSurfaceBeOS :: IsOffscreen(PRBool *aOffScreen)
00133 {
00134   *aOffScreen = mIsOffscreen;//mBitmap ? PR_TRUE : PR_FALSE;
00135   return NS_OK;
00136 }
00137 
00138 NS_IMETHODIMP nsDrawingSurfaceBeOS :: IsPixelAddressable(PRBool *aAddressable)
00139 {
00140   *aAddressable = PR_FALSE; 
00141   return NS_OK;
00142 }
00143 
00144 NS_IMETHODIMP nsDrawingSurfaceBeOS :: GetPixelFormat(nsPixelFormat *aFormat)
00145 {
00146   *aFormat = mPixFormat;
00147   return NS_OK;
00148 }
00149 
00150 NS_IMETHODIMP nsDrawingSurfaceBeOS :: Init(BView *aView)
00151 {
00152   if (aView->LockLooper()) 
00153   { 
00154     //remember dimensions 
00155     BRect r = aView->Bounds();
00156     mWidth = nscoord(r.IntegerWidth() + 1);
00157     mHeight = nscoord(r.IntegerHeight() + 1);
00158     
00159     mView = aView;
00160     aView->UnlockLooper(); 
00161   } 
00162  
00163   // onscreen View, attached to BWindow, acquired via GetNativeData() call in nsRendering
00164   mIsOffscreen = PR_FALSE; 
00165   return NS_OK;
00166 }
00167 
00168 NS_IMETHODIMP nsDrawingSurfaceBeOS :: Init(BView *aView, PRUint32 aWidth,
00169                                           PRUint32 aHeight, PRUint32 aFlags)
00170 {
00171   NS_ASSERTION(!(aView == nsnull), "null BView");
00172 
00173   //remember dimensions
00174   mWidth=aWidth;
00175   mHeight=aHeight;
00176   mFlags = aFlags; 
00177   
00178   //creating offscreen  backbuffer surface
00179   mIsOffscreen = PR_TRUE; 
00180   //TODO: Maybe we should reuse BView by resizing it, 
00181   //and also reuse BBitmap if new size is = < of current size
00182   BRect r(0,0, mWidth-1, mHeight-1);
00183   //creating auxiliary BView to draw on offscreen BBitmap
00184   mView = new BView(r, "", 0, 0);
00185   if (!mView)
00186     return NS_ERROR_OUT_OF_MEMORY;
00187 
00188 //if((aFlags & NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS) &&
00189 //  (aWidth > 0) && (aHeight > 0))
00190   if (aWidth > 0 && aHeight > 0)
00191   {
00193     mBitmap = new BBitmap(r, B_RGBA32, true);
00194     if (!mBitmap)
00195       return NS_ERROR_OUT_OF_MEMORY;
00196 
00197     if (mBitmap->InitCheck()!=B_OK)
00198     {
00199       //for some reason, the bitmap isn't valid - delete the
00200       //bitmap object, then indicate failure
00201       delete mBitmap;
00202       mBitmap=NULL;
00203       return NS_ERROR_FAILURE;
00204     }
00205     
00206     //NB! Locking bitmap for lifetime to avoid unneccessary locking at each
00207     //drawing primitive call. Locking is quite time-expensive.
00208     //To avoid it, we call surface->LockDrawable() instead LockLooper()
00209     mBitmap->Lock();
00210     //Setting ViewColor transparent noticeably decreases AppServer load in DrawBitmp()
00211     //Applicable here, because Mozilla paints backgrounds explicitly, with images or filling areas.
00212     mView->SetViewColor(B_TRANSPARENT_32_BIT);
00213     mBitmap->AddChild(mView);
00214   }
00215   
00216   return NS_OK;
00217 }
00218 
00219 NS_IMETHODIMP nsDrawingSurfaceBeOS :: AcquireView(BView **aView) 
00220 {
00221   *aView = mView;
00222   return NS_OK;
00223 }
00224 
00225 NS_IMETHODIMP nsDrawingSurfaceBeOS :: AcquireBitmap(BBitmap **aBitmap)
00226 {
00227   if (mBitmap && mView)
00228   {
00229     mView->Sync();
00230   }
00231   *aBitmap = mBitmap;
00232 
00233   return NS_OK;
00234 }
00235 
00236 NS_IMETHODIMP nsDrawingSurfaceBeOS :: ReleaseView(void)
00237 {
00238   return NS_OK;
00239 }
00240 
00241 NS_IMETHODIMP nsDrawingSurfaceBeOS :: ReleaseBitmap(void)
00242 {
00243   return NS_OK;
00244 }
00245 
00246 bool nsDrawingSurfaceBeOS :: LockDrawable()
00247 {
00248   //TODO: try to avoid exta locking also for onscreen BView.
00249   //Perhaps it needs synchronization with widget through nsToolkit and lock counting.
00250   bool rv = false;
00251   if (!mBitmap)
00252   {
00253     // Non-bitmap (onscreen) view - unlock it as required if exists
00254     rv = mView && mView->LockLooper();
00255   }
00256   else
00257   {
00258     // Was locked in Init(), only test for locked state here
00259        rv = mBitmap->IsLocked();
00260   }
00261   return rv;
00262 }
00263 
00264 void nsDrawingSurfaceBeOS :: UnlockDrawable()
00265 {
00266   // Do nothing, bitmap is locked for lifetime in our implementation
00267   if (mBitmap)
00268     return;
00269   // Non-bitmap (onscreen) view - unlock it as required.
00270   // mBitmap may be gone in destroy process, so additional check for Looper()
00271   if (mView  && mView->Looper())
00272     mView->UnlockLooper();
00273 }